  IrTcl User's Guide and Reference
  Index Data, info@indexdata.dk
  $Date: 2001/12/03 18:52:06 $

  IrTcl version 1.4 -- a Tcl extension that allows you to build Z39.50
  clients.
  ______________________________________________________________________

  Table of Contents


  1. Introduction
  2. Compilation and installation
     2.1 UNIX
     2.2 WIN32
     2.3 Using Tk

  3. Overview of the API
  4. Associations
     4.1 Connect
     4.2 Init
     4.3 Disconnect

  5. Result sets
     5.1 Queries
     5.2 Search
     5.3 Present
     5.4 Records
     5.5 MARC records
     5.6 SUTRS
     5.7 GRS-1
     5.8 Explain

  6. Scan
  7. License
  8. About Index Data
  9. References


  ______________________________________________________________________

  1.  Introduction

  This document describes the IrTcl information retrieval toolkit, which
  offers a high-level interface for the development of Z39.50 clients.
  The toolkit is based on the Tcl/Tk toolkit developed by Prof. John K.
  Ousterhout at the University of California [ref 1].  The core of Tcl
  is rather small but it offers a flexible C API for easy development of
  Tcl extensions. The most important Tcl extension is probably Tk -- A
  portale GUI for X/WIN32/MAC.

  To interface the Z39.50 protocol IrTcl uses the YAZ toolkit.

  IrTcl is usually build as a dynamic library (WIN32) or a shared object
  (Unix) which is dynamically loaded by using the Tcl's load command.
  However, IrTcl can also be compiled as a traditional static library.


  2.  Compilation and installation


  2.1.  UNIX

  In order to compile the software on UNIX you need:


  o  An ANSI C compiler such as GNU C.

  o  Tcl.  Version 8.0 and 8.3 has been tested.

  o  YAZ version 1.6 or higher.

  Unpack the IrTcl package at the same directory level as YAZ.

  Type:


       $ ./configure



  This command tries to configure IrTcl for your system and creates a
  Makefile.

  The configure script tries to locate the file tclConfig.sh which
  should be generated by Tcl's installation script. Configure looks for
  ther Tcl shell on your system in order to locate this file.  For
  example if tclsh is located in /home/joe/bin, configure will assume
  that tclConfig.sh is installed in /home/joe/lib, in which case the
  prefix is /home/joe. If you have more than one Tcl version installed
  on your system, or if configure cannot find the tclConfig.sh, you can
  specify in which directory it is, by supplying option --with-tclconfig
  - for example:


       $ ./configure --with-tclconfig=/home/joe/lib



  The IrTcl executables are installed in prefix/bin and libraries and
  support files are installed in prefix/irtcl.

  Compile IrTcl by typing:


       $ make



  For Tcl versions that support dynamic libraries the command above will
  create the shared library, irtcl.so, as well as the normal static
  library, libirtcl.a.

  For Tcl versions that doesn't support dynamic libraries the make
  command will create two shells will build-in IrTcl support -- a Tcl
  shell called ir-tcl. The traditional static library, libirtcl.a, is
  build as well.

  To install the programs and support files type:


       $ make install



  If you wish to install man pages type:


  $ make install.man



  Summary of files installed (the names refer to the Makefile
  variables):


     irtcl.so
        The IrTcl shared dynamic library.  The actual name of this
        library vary. Installed in IRTCLDIR.  This file is only
        generated when using newer versions of Tcl/Tk.


     ir-tcl
        The IrTcl shell for Tcl. This program is not needed when using a
        Tcl that supports shared libraries. Installed in BINDIR --
        defaults to /usr/local/bin.


     client.tcl
        A graphical client for Tk.  The client is installed as an
        executable script called irclient in BINDIR. This client needs a
        number of files, bitmaps, etc.  The client looks for the files
        in the current directory -- if this fails it tries to look in
        the directory IRTCLDIR -- defaults to /usr/local/lib/irtcl.


     libirtcl.a
        The IrTcl library.  Installed in LIBDIR -- defaults to
        /usr/local/lib.


     ir-tcl.h
        The IrTcl header file.  Installed in INCDIR -- defaults to
        /usr/local/include.


     irtdb.tcl
        A setup file with definitions of target and queries. Read and
        updated by client.tcl. Installed in IRTCLDIR -- defaults to
        /usr/local/lib/irtcl.


     formats/*
        Display format files written in Tk. Read by client.tcl.
        Installed in IRTCLDIR -- defaults to /usr/local/lib/irtcl.


     bitmaps/*
        Various bitmap files. Read by client.tcl. Installed in IRTCLDIR
        -- defaults to /usr/local/lib/irtcl.


     LICENSE
        LICENSE file. Read by client.tcl. Installed in IRTCLDIR --
        defaults to /usr/local/lib/irtcl.


  IrTcl can be used either from the Tcl interpreter tclsh or the
  statically linked program ir-tcl.  Using tclsh is the preferred
  method. You must load the IrTcl library by using the load command.

  A static, non-dynamic, version goes like this:

     $ ir-tcl
     %



  and the dynamic version (preferred) goes like:


          $ tclsh
          % load ./irtcl.tcl
          %



  2.2.  WIN32


  IrTcl is shipped with a "makefile" for the NMAKE tool part of with
  Microsoft Visual C++.

  Start an MS-DOS prompt and switch the sub directory WIN where the file
  makefile is located. Customize the installation by editing the
  makefile file (for example by using wordpad).

  The following summarises the most important settings in that file.


     YAZDIR
        Specifies where YAZ is located.

     DEBUG
        If set to 1, the software is compiled with debugging libraries.
        If set to 0, the software is compiled with release (non-
        debugging) libraries.

  When satisfied with the settings in the makefile type


       nmake



  If compilation was successful the executables irtcl.dll is put in
  directory BIN.

  To start the test client that comes with IrTcl make sure both YAZ.DLL
  and IRTCL.DLL are in current directory or in your PATH. Go to the top-
  level directory of IrTcl and type "wish -f client.tcl". You might want
  to make a short-cut to start this.


  2.3.  Using Tk

  If your Tcl/Tk supports dynamic libraries you can use the load command
  from within wish as described in the previous section.

  The enclosed script client.tcl is a graphical client which demonstates
  an example of a user interface for the Z39.50 protocol.  At first the
  script was relatively small but it has grown since the beginning. At
  present it is about 3000 lines.


  To start the client with dynamic library support use:


       $ wish -f client.tcl



  Note: Substitute the real name for the wish interpreter above, for
  version 8.0 it is probably called wish8.0.

  The client lets up define targets and query types within the
  interface.  Hence, you will not need to modify configuration files.

  Stuff regarding targets can be found in the pull down menu 'Target'
  with the following options:

     Connect
        Establishes connection to a target.

     Disconnect
        Closes a target connection.

     About
        Shows implementation Id, implementation Version, etc for the
        current target.

     Setup
        Pops up a target definition window. You may alter a target
        definition.

     Setup new
        Lets you define a new target.


  The term query type refers to a collection of search fields. The pull
  down menu Options|Query deals with queries. You may
  insert/modify/remove query types.


  3.  Overview of the API

  Basically, IrTcl is a set of commands introduced to Tcl.  When
  extending Tcl there are two approaches: action-oriented commands and
  object-oriented commands.

  Action-oriented commands manipulate Tcl variables and each command
  introduces only one action.  The string manipulation commands in Tcl
  are action oriented.

  Object-oriented commands are added for every declared variable
  (object). Object-oriented commands usually provide a set of actions
  (methods) to manipulate the object.  The widgets in Tk (X objects) are
  examples of the object-oriented style.

  IrTcl commands are object-oriented. The main reason for this is that
  the data structures involved in the IR protocol are not easily
  represented by Tcl data structures.  Also, the IrTcl objects tend to
  exist for a relativly long time.  Note that although we use the term
  object-oriented commands, this does not mean that the programming
  style is strictly object-oriented. For example, there is such no such
  thing as inheritance.

  We are now ready to present the three commands introduced to Tcl by
  IrTcl:

     ir The ir object represents a connection to a target. More
        precisely it describes a Z-association.

     ir-set
        The ir-set describes a result set, which is conceptually a
        collection of records returned by the target.  The ir-set object
        may retrieve records from a target by means of the ir object; it
        may read/write records from/to a local file or it may be updated
        with a user-edited record.

     ir-scan
        The scan object represents a list of scan lines retrieved from a
        target.

  Example

  To create a new IR object called z-assoc write:


          ir z-assoc



  End of example

  Each object provides a set of settings which may either be readable,
  writeable of both. All settings immediately follow the name of the
  object. If a value is present the setting is set to value.

  Example

  We wish to set the preferred-message-size to 18000 on the z-assoc
  object:



          z-assoc preferredMessageSize 18000



  To read the current value of preferred-message-size use:



          z-assoc preferredMessageSize



  End of example

  One important category consists of settings is those that relate to
  the event-driven model. When IrTcl receives responses from the target,
  i.e.  init responses, search responses, etc., a callback routine is
  called. Callback routines are represented in Tcl as a list, which is
  re-interpreted prior to invocation.  The method is similar to the one
  used in Tk to capture X events.

  For each Z39.50 request there is a corresponding object action. The
  most important actions are:

     connect
        Establishes connection with a target

     init
        Sends an initialize request.

     search
        Sends a search request.

     present
        Sends a present request.

     scan
        Sends a scan request.

  Example

  This example shows a complete connect - init - search - present
  scenario.

  First an IR object, called z, is created.  Also a result set z.1 is
  introduced by the ir-set and it is specified that the result set uses
  z as its association.

  The setting databaseNames is set to the database books to which the
  following searches are directed.  A callback is then defined and a
  connection is established to fake.com by the connect action.  If the
  connect succeeds the connect-response is called.

  In the Tcl procedure, connect-response, a callback is defined before
  the init request is executed.  The Tcl procedure init-response is
  called when a init response is returned from the target.

  The init-response procedure sets up a search-response callback handler
  and sends a search-request by using a query which consists of a single
  word science.

  When the search-response procedure is called it defines a variable
  hits and sets it to the value of the setting resultCount. If hits is
  positive a present-request is sent -- asking for 5 records from
  position 1.

  Finally, a present response is received and the number of records
  returned is stored in the variable ret.



  ir z
  z databaseNames books
  ir-set z.1 z
  z callback {connect-response}
  z connect fake.com

  proc connect-response {} {
      z callback {init-response}
      z init
  }

  proc init-response {} {
      z callback {search-response}
      z.1 search science
  }

  proc search-response {} {
      set hits [z.1 resultCount]
      puts "$hits hits"
      if {$hits > 0} {
          z callback {present-response}
          z.1 present 1 5
      }
  }

  proc present-response {} {
      set ret [z.1 numberOfRecordsReturned]
      puts "$ret records returned"
  }



  End of example

  The previous example program doesn't care about error conditions.  If
  errors occur in the program they will be trapped by the Tcl error
  handler. This is not always appropriate. However, Tcl offers a catch
  command to support error handling by the program itself.


  4.  Associations

  The ir object describes an association with a target.  This section
  covers the connect-init-disconnect actions provided by the ir object.
  An ir object is created by the ir command and the created object
  enters a 'not connected' state, because it isn't connected to a target
  yet.


  4.1.  Connect

  A connection is established by the connect action which is immediately
  followed by a hostname. A number of settings affect the connect
  action. Obviously, these settings should be set before connecting. The
  settings are:


     comstack mosi|tcpip
        Comstack type. Note that mosi is no longer supported by YAZ.

     protocol Z39|SR
        Protocol type - ANSI/NISO Z39.50 or ISO SR. Note, that SR is no
        longer supported by YAZ.


     callback list
        Tcl script called when the connection is established.

     failback list
        Fatal error Tcl script. Called on protocol errors or if target
        closes connection.

  If the connect is unsuccessful either the connect action itself will
  return an error code or the failback handler is invoked.

  In general, the failback handler is invoked when serious unrecoverable
  errors occur when communicating with the target.  In this case the
  IrTcl system shuts down the connection.  The failback handler might
  inspect the failInfo setting to determine the cause of the failure; it
  returns two elements. The first is an error integer; the second is an
  english representation of the error. The error codes and the
  corresponding messages are:


     0  ok

     1  connect failed

     2  connection closed

     3  connection closed

     4  failed to decode incoming APDU

     5  unknown APDU

  Note: in case 3 the connection was closed during read a read operation
  whereas in case 4 it was closed during a write operation.


  4.2.  Init

  If the connect operation succeeds the init action should be used.  The
  init related settings are:


     preferredMessageSize integer
        Preferred-message-size. Default value is 30000.

     maximumRecordSize integer
        Maximum-record-size. Default value is 30000.

     idAuthentication string ...
        Id-authentication. There are three forms. If any empty is given,
        the Id-authentication is not used.  If one non-empty string is
        given, the 'open' authentication is used. If three strings are
        specified, the version 'id-pass' authentication (version 3 only)
        is used in which case the first string is groupId; the second
        string is userId and the third string is password.

     implementationName string
        Implementation-name of origin system.

     implementationId
        Implementation-id of origin system. This setting is read-only.

     implementationVersion
        Implementation-version of origin system. This settings is read-
        only.


     options list
        Options to be negotiated in the init service. The list contains
        the options that are set. Possible values are search, present,
        delSet, resourceReport, triggerResourceCtrl, resourceCtrl,
        accessCtrl, scan, sort, extendedServices, level-1Segmentation,
        level-2Segmentation, concurrentOperations and namedResultSets.
        Currently the default options are: search, present, scan and
        namedResultSets. The options setting is set to its default value
        when an ir object is created and when a disconnect action is
        performed.

     protocolVersion integer
        Protocol version: 2, 3, etc. Default is 2.

     referenceId string
        Reference-id of init operation. If string is empty no reference-
        id is used.

     initResponse list
        Init-response Tcl script.

     callback list
        General response Tcl script. Only used if initResponse is not
        specified.

  The init-response handler should inspect some of the settings shown
  below:


     initResult returns boolean
        Init response status. True if init operation was successful;
        false otherwise.

     preferredMessageSize returns integer
        Preferred-message-size after negotiation.

     maximumRecordSize returns integer
        Maximum-record-size after negotiation.

     targetImplementationName returns string
        Implementation-name of target system.

     targetImplementationId returns string
        Implementation-id of target system.

     targetImplementationVersion returns string
        Implementation-version of target system.

     options returns list
        Options after negotiation. The list contains the options that
        are set.

     protocolVersion returns integer
        Protocol version: 2, 3, etc after negotiation.

     userInformationField returns string
        User information field.

     referenceId returns string
        Reference-id of init response.

  Example

  Consider a client with the ability to access multiple targets.


  We define a list of targets that we wish to connect to.  Each item in
  the list describes the target parameters with the following four
  components: association-name, comstack-type, protocol-type and a
  hostname.

  The list for the two targets: Library of Congress and Z39.50 target
  Data Research, will be defined as:


       set targetList { {loc tcpip Z39 z3950.loc.gov:7090}
                        {drs tcpip Z39 dranet.dra.com} }



  The Tcl code below defines, connect and initialize the targets in
  targetList:



       foreach target $targetList {
           set assoc [lindex $target 0]
           ir $assoc
           $assoc comstack [lindex $target 1]
           $assoc protocol [lindex $target 2]
           $assoc failback [list fail-response $assoc]
           $assoc callback [list connect-response $assoc]
           $assoc connect [lindex $target 3]
       }

       proc connect-response {assoc} {
           $assoc callback [list init-response $assoc]
           $assoc init
       }

       proc fail-response {assoc} {
           puts "$assoc closed connection or protocol error"
       }

       proc init-response {assoc} {
           if {[$assoc initResult]} {
               puts "$assoc initialized ok"
           } else {
               puts "$assoc didn't initialize"
           }
       }



  target is bound to each item in the list of targets.  The assoc is set
  to the ir object name.  Then, the comstack, protocol and failback are
  set for the assoc object.  The ir object name is argument to the fail-
  response and connect-response routines.  Note the use of the Tcl list
  command which is necessary here because the argument contains
  variables (assoc) that should be substituted before the handler is
  defined.  After the connect operation, the init-response handler is
  defined in much the same way as the failback handler.  And, finally,
  an init request is executed.

  End of example



  4.3.  Disconnect

  To terminate the connection the disconnect action should be used.
  This action has no parameters.  Another connection may be established
  by a new connect action on the same ir object.


  5.  Result sets

  This section covers the queries used by IrTcl, and how searches and
  presents are handled.

  A search operation and a result set is described by the ir set object.
  The ir set object is defined by the ir-set command which has two
  parameters. The first is the name of the new ir set object, and the
  second, which is optional, is the name of an assocation -- an ir
  object. The second argument is required if the ir set object should be
  able to perform searches and presents. However, it is not required if
  only ``local'' operations is done with the ir set object.

  When the ir set object is created a number of settings are inherited
  from the ir object, such as the selected databass, query type, etc.
  Thus, the ir object contains what we could call default settings.


  5.1.  Queries

  Search requests are sent by the search action which takes a query as
  parameter. There are two types of queries, RPN and CCL, controlled by
  the setting queryType.  A string representation for the query is used
  in IrTcl since Tcl has reasonably powerful string manipulaton
  capabilities.  The RPN query used in IrTcl is the prefix query
  notation also used in the YAZ test client.

  The CCL query is an uninterpreted octet-string which is parsed by the
  target.  We refer to the standard: ISO 8777. Note that only a few
  targets actually support the CCL query and the interpretation of the
  standard may vary.

  The prefix query notation (which is converted to RPN) offer a few
  operators. They are:


     @attr list op
        The attributes in list are applied to op

     @and op1 op2
        Boolean and on op1 and op2

     @or op1 op2
        Boolean or on op1 and op2

     @not op1 op2
        Boolean not on op1 and op2

     @prox list op1 op2
        Proximity operation on op1 and op2. Not implemented yet.

     @set name
        Result set reference

     @attrset set
        Whole query uses the specified attribute set. If this operator
        is used it must be defined at the beginning of the query.


  It is simple to build RPN queries in IrTcl. Search terms are sequences
  of characters, as in:


          science



  Boolean operators use the prefix notation (instead of the suffix/RPN),
  as in:


          @and science technology



  Search terms may be associated with attributes. These attributes are
  indicated by the @attr operator.  Assuming the bib-1 attribute set, we
  can set the use-attribute (type is 1) to title (value is 4):



          @attr 1=4 science



  Also, it is possible to apply attributes to a range of search terms.
  In the query below, both search terms have use=title but the tech term
  is right truncated:



          @attr 1=4 @and @attr 5=1 tech beta



  To search for the DatabaseInfo records from an Explain server, we
  could use


          @attrset exp1 @attr 1=1 DatabaseInfo



  5.2.  Search

  The settings that affect the search are listed below:


     databaseNames list
        Database-names.

     smallSetUpperBound integer
        Small set upper bound. Default 0.

     largeSetLowerBound integer
        Large set lower bound. Default 2.

     mediumSetPresentNumber integer
        Medium set present number. Default 0.
     replaceIndicator boolean
        Replace-indicator. Default true (1).

     setName string
        Name of result set. Default name of set is default.

     queryType rpn|ccl
        Query type-1 or query type-2. Default rpn (type-1).

     preferredRecordSyntax string
        Preferred record syntax -- UNIMARC, USMARC, etc.

     smallSetElementSetNames string
        small-set-element-set names. If string is empty the element set
        is not set. Default is empty (not set).

     mediumSetElementSetNames string
        medium-set-element-set names. If string is empty the element set
        is not set. Default is empty (not set).

     nextResultSetPosition returns integer
        Next result set position.

     referenceId string
        Reference-id. If string is empty no reference-id is used.

     searchResponse list
        Search-response Tcl script.

     callback list
        General response Tcl script. Only used if searchResponse is not
        specified.  This setting is valid only for the ir object -- not
        the ir-set object.

  Setting the databaseNames is mandatory. All other settings have
  reasonable defaults.  The search-response handler, specified by the
  callback - or the searchResponse setting, should read some of the
  settings shown below:


     searchStatus returns boolean
        Search-status. True if search operation was successful; false
        otherwise.

     responseStatus returns list
        Response status information.

     resultCount returns integer
        result-count

     numberOfRecordsReturned returns integer
        Number of records returned.

     referenceId returns string
        Reference-id of search response.

  The responseStatus signals one of three conditions which is indicated
  by the value of the first item in the list:


     NSD
        indicates that the target has returned one or more non-surrogate
        diagnostic messages. The NSD item is followed by a list with all
        non-surrogate messages. Each non-surrogate message consists of
        three items. The first item of the three items is the error code
        (integer); the next item is a textual representation of the
        error code in plain english; the third item is additional
        information, possibly empty if no additional information was
        returned by the target.


     DBOSD
        indicates a successful operation where the target has returned
        one or more records. Each record may be either a database record
        or a surrogate diagnostic.


     OK indicates a successful operation -- no records are returned from
        the target.

  Example

  We continue with the multiple-targets example.  The init-response
  procedure will attempt to make searches:



       proc init-response {assoc} {
           puts "$assoc connected"
           ir-set ${assoc}.1 $assoc
           $assoc.1 queryType rpn
           $assoc.1 databaseNames base-a base-b
           $assoc callback [list search-response $assoc ${assoc}.1]
           $assoc.1 search "@attr 1=4 @and @attr 5=1 tech beta"
       }



  An ir set object is defined and the ir object is told about the name
  of ir object.  The ir set object use the name of the ir object as
  prefix.

  Then, the query-type is defined to be RPN, i.e. we will use the prefix
  query notation later on.

  Two databases, base-a and base-b, are selected.

  A search-response handler is defined with the ir object and the ir-set
  object as parameters and the search is executed.

  The first part of the search-response looks like:


       proc search-response {assoc rset} {
           set status [$rset responseStatus]
           set type [lindex $status 0]
           if {$type == "NSD"} {
               set code [lindex $status 1]
               set msg [lindex $status 2]
               set addinfo [lindex $status 3]
               puts "NSD $code: $msg: $addinfo"
               return
           }
           set hits [$rset resultCount]
           if {$type == "DBOSD"} {
               set ret [$rset numberOfRecordsReturned]
               ...
           }
       }


  The response status is stored in variable status and the first element
  indicates the condition.  If non-surrogate diagnostics are returned
  they are displayed.  Otherwise, the search was a success and the num-
  ber of hits is read. Finally, it is tested whether the search response
  returned records (database or diagnostic).

  Note that we actually didn't inspect the search status (setting
  searchStatus) to determine whether the search was successful or not,
  because the standard specifies that one or more non-surrogate
  diagnostics should be returned by the target in case of errors.

  End of example

  If one or more records are returned from the target they will be
  stored in the result set object.  In the case in which the search
  response contains records, it is very similar to the present response
  case. Therefore, some settings are common to both situations.


  5.3.  Present

  The present action sends a present request. The present is followed by
  two optional integers. The first integer is the result-set starting
  position -- defaults to 1. The second integer is the number of records
  requested -- defaults to 10.  The settings which could be modified
  before a present action are:


     preferredRecordSyntax string
        preferred record syntax -- UNIMARC, USMARC, etc.

     elementSetNames string
        Element-set names. If string is empty the element set is not
        set. Default is empty (not set).

     referenceId string
        Reference-id. If string is empty no reference-id is used.

     presentResponse list
        Present-response Tcl script.

     callback list
        General response Tcl script. Only used if presentResponse is not
        specified This setting is valid only for the ir object -- not
        the ir-set object.

  The present-response handler should inspect the settings shown in
  table below.  Note that responseStatus and numberOfRecordsReturned
  settings were also used in the search-response case.

  As in the search response case, records returned from the target are
  stored in the result set object.


     presentStatus returns boolean
        Present-status.

     responseStatus returns list
        Response status information.

     numberOfRecordsReturned returns integer
        Number of records returned.

     nextResultSetPosition returns integer
        Next result set position.

     referenceId returns string
        Reference-id of present response.


  5.4.  Records

  Search responses and present responses may result in one or more
  records stored in the ir set object if the responseStatus setting
  indicates database or surrogate diagnostics (DBOSD). The individual
  records, indexed by an integer position offset, should then be
  inspected.

  If element set names have been specified either in the search requests
  (smallSetElementSetNames / mediumSetElementSetNames) or present
  requests (elementSetNames) the individual records in the ir set object
  are assigned appropriate element set ids.  In this mode records at a
  given position are treated different as long as they have difference
  element set ids.  To inspect records with a particular element set id
  in subsequent operations use the recordElements setting followed by
  the id.  If you have more than one record at a given position and you
  do not use recordElements the record selected at the given position is
  undefined.

  The action type followed by an integer returns information about a
  given position in an ir set. There are three possiblities:


     SD The item is a surrogate diagnostic record.

     empty
        There is no record at the specified position.

     DB The item is a database record.

  To handle the first case, surrogate diagnostic record, the Diag action
  should be used. It returns three items: error code (integer), text
  representation in plain english (string), and additional information
  (string, possibly empty).

  In the second case, no record, note that there still might be a record
  at the position but with an id that differs from that specified by
  recordElements.

  In the third case, database record, the recordType action should be
  used. It returns the record type at the given position.  Some record
  types are:


       UNIMARC INTERMARC CCF USMARC UKMARC NORMARC LIBRISMARC DANMARC FINMARC
       SUTRS


  Example

  We continue our search-response example. In the case, DBOSD, we should
  inspect the result set items.  Recall that the ir set name was passed
  to the search-response handler as argument rset.



      if {$type == "DBOSD"} {
          set ret [$rset numberOfRecordsReturned]
          for {set i 1} {$i<=$ret} {incr i} {
              set itype [$rset type $i]
              if {$itype == "SD"} {
                  set diag [$rset Diag $i]
                  set code [lindex $diag 0]
                  set msg [lindex $diag 1]
                  set addinfo [lindex $diag 2]
                  puts "$i: NSD $code: $msg: $addinfo"
              } elseif {$itype == "DB"} {
                  set rtype [$rset recordType $i]
                  puts "$i: type is $rtype"
              }
          }
      }



  Each item in the result set is examined.  If an item is a diagnostic
  message it is displayed; otherwise if it's a database record its type
  is displayed.

  End of example


  5.5.  MARC records

  In the case, where there is a MARC record at a given position we want
  to display it somehow. The action getMarc is what we need.  The
  getMarc is followed by a position integer and the type of extraction
  we want to make: field or line.

  The field and line type are followed by three parameters that serve as
  extraction masks.  They are called tag, indicator and field.  If the
  mask matches a tag/indicator/field of a record the information is
  extracted. Two characters have special meaning in masks: the dot (any
  character) and star (any number of any character).

  The field type returns one or more lists of field information that
  matches the mask specification. Only the content of fields is
  returned.

  The line type, on the other hand, returns a Tcl list that completely
  describe the layout of the MARC record -- including tags, fields, etc.

  The field type is sufficient and efficient in the case, where only a
  small number of fields are extracted, and in the case where no further
  processing (in Tcl) is necessary.

  However, if the MARC record is to be edited or altered in any way, the
  line extraction is more powerful -- only limited by the Tcl language
  itself.

  Example

  Consider the record below:



  001       11224466
  003    DLC
  005    00000000000000.0
  008    910710c19910701nju           00010 eng
  010    $a    11224466
  040    $a DLC $c DLC
  050 00 $a 123-xyz
  100 10 $a Jack Collins
  245 10 $a How to program a computer
  260 1  $a Penguin
  263    $a 8710
  300    $a p. cm.



  Assuming this record is at position 1 in ir-set z.1, we might extract
  the title-field (245 * a), with the following command:


       z.1 getMarc 1 field 245 * a



  which gives:


       {How to program a computer}



  Using the line instead of field gives:


       {245 {10} {{a {How to program a computer}} }}



  If we wish to extract the whole record as a list, we use:


       z.1 getMarc 1 line * * *



  giving:


       {001 {} {{{} {   11224466 }} }}
       {003 {} {{{} DLC} }}
       {005 {} {{{} 00000000000000.0} }}
       {008 {} {{{} {910710c19910701nju           00010 eng  }} }}
       {010 {  } {{a {   11224466 }} }}
       {040 {  } {{a DLC} {c DLC} }}
       {050 {00} {{a 123-xyz} }}
       {100 {10} {{a {Jack Collins}} }}
       {245 {10} {{a {How to program a computer}} }}
       {260 {1 } {{a Penguin} }}
       {263 {  } {{a 8710} }}
       {300 {  } {{a {p. cm.}} }}


  End of example

  Example

  This example demonstrates how Tcl can be used to examine a MARC record
  in the list notation.

  The procedure extract-format makes an extraction of fields in a MARC
  record based on a number of masks.  There are 5 parameters, r: a
  record in list notation, tag: regular expression to match the record
  tags, ind: regular expression to match indicators, field: regular
  expression to match fields, and finally text: regular expression to
  match the content of a field.



       proc extract-format {r tag ind field text} {
           foreach line $r {
               if {[regexp $tag [lindex $line 0]] && \
                       [regexp $ind [lindex $line 1]]} {
                   foreach f [lindex $line 2] {
                       if {[regexp $field [lindex $f 0]]} {
                           if {[regexp $text [lindex $f 1]]} {
                               puts [lindex $f 1]
                           }
                       }
                   }
               }
           }
       }



  To match comput followed by any number of character(s) in the 245
  fields in the record from the previous example, we could use:


       set r [z.1 getMarc 1 line * * *]

       extract-format $r 245 .. . comput



  which gives:


       How to program a computer



  End of example

  The putMarc action does the opposite of getMarc. It copies a record in
  Tcl list notation to a ir set object and is needed if a result-set
  must be updated by a Tcl modified (user-edited) record.


  5.6.  SUTRS

  In IrTcl a SUTRS record is treated as one single string. To retrieve a
  SUTRS record use the getSutrs followed by an index.


  5.7.  GRS-1

  A GRS-1 record in IrTcl is represented as a list of elements.  Each
  element specifies a tag as well as data. The data may be a subtree,
  which is represented as a list, and so on.

  The method getGrs is followed by a record index and optional
  specifiers that selects a specific sub-tree. Each element consists of
  5 elements:


     tag-set
        Tag set number.


     value-type
        Type of tag value. May be either numeric of string.


     value
        The value it self.


     data-type
        May be either octets, numeric, ext, string, bool, intUnit,
        empty, notRequested, diagnostic or subtree.


     data
        The data associated with element of given type as indicated
        before. If data-type is numeric or string then data is encoded
        as a single Tcl token. The data-type bool is encoded as 0 or 1
        for false and  true respectively. If the data-type is subtree
        the data is a sub-list.  In all other cases, the data is the
        empty string.

  Example

  Consider the GRS-1 record below as shown by the YAZ client program:



       (1,1) OID: GILS-schema
       (1,14) 2
       (2,1)  UTAH EARTHQUAKE EPICENTERS
           class=4,type=1,value=us
       (4,52) UTAH GEOLOGICAL AND MINERAL SURVEY
       (3,Local-Subject-Index) APPALACHIAN VALLEY; EARTHQUAKE; EPICENTER
       (2,6)
           (1,19) Five files of epicenter data arranged by ...
           (3,Format) DIGITAL DATA SETS
           (3,Data-Category) TERRESTRIAL
           (3,Comments) Data are supplied by the University of Utah ...
       (4,70)
           (4,90)
               (2,10) UTAH GEOLOGICAL AND MINERAL SURVEY
               (4,2) 606 BLACK HAWK WAY
               (4,3) SALT LAKE CITY
               (3,State) UT
               (3,Zip-Code) 84108
               (2,16) USA
               (2,14) (801) 581-6831
           (4,7) UTAH EARTHQUAKE EPICENTERS
       (4,1) ESDD0006
       (1,16) 198903

  The record may be fetched from the result set, z.1, at position 1 by
  using:


       z.1 getGrs 1



  which will return:


       { 1 numeric 1 oid 1.2.840.10003.13.2 }
       { 1 numeric 14 string 2 }
       { 2 numeric 1 string
          { UTAH EARTHQUAKE EPICENTERS} }
       { 4 numeric 52 string {UTAH GEOLOGICAL AND MINERAL SURVEY} }
       { 3 string Local-Subject-Index string
          {APPALACHIAN VALLEY; EARTHQUAKE; EPICENTER} }
       { 2 numeric 6 subtree
          { { 1 numeric 19 string
             {Five files of epicenter data arranged by ...} }
          { 3 string Format string {DIGITAL DATA SETS} }
          { 3 string Data-Category string TERRESTRIAL }
          { 3 string Comments string
             {Data are supplied by the University of Utah ...} } } }
       { 4 numeric 70 subtree
          { { 4 numeric 90 subtree
             { { 2 numeric 10 string
                {UTAH GEOLOGICAL AND MINERAL SURVEY} }
             { 4 numeric 2 string {606 BLACK HAWK WAY} }
             { 4 numeric 3 string {SALT LAKE CITY} }
             { 3 string State string UT }
             { 3 string Zip-Code string 84108 }
             { 2 numeric 16 string USA }
             { 2 numeric 14 string {(801) 581-6831} } } }
             { 4 numeric 7 string {UTAH EARTHQUAKE EPICENTERS} } } }
       { 4 numeric 1 string ESDD0006 }
       { 1 numeric 16 string 198903 }



  We can choose only to get the path (2,6) by using:



       z.1 getGrs 1 (2,6)



  and we'll get:


       { 2 numeric 6 subtree { { 1 numeric 19 string
          {Five files of epicenter data arranged by ...} }
          { 3 string Format string {DIGITAL DATA SETS} }
          { 3 string Data-Category string TERRESTRIAL }
          { 3 string Comments
             string {Data are supplied by the University of Utah ...} } } }



  To get the well known (1,19) within the subject (2,6) we use


       z.1 getGrs 1 (2,6) (1,19)



  and get:


       { 2 numeric 6 subtree
          { { 1 numeric 19 string
             {Five files of epicenter data arranged by ...} } } }



  End of example


  5.8.  Explain

  Explain records are retrieved like other records. The method,
  getExplain is followed by an index and and an optional Explain record
  pattern.

  The returned record is a canonical representation of the Explain
  record.  An ASN.1 sequence is represented as a list. Each item in the
  list consists of the name of the element, followed by its value if the
  value is supplied.

  The optional pattern that follows the index after getExplain consists
  of one or more elements, that is matched against the elements of the
  actual record.

  Example

  One of the few targets that support explain is the ATT research server
  at z3950.research.att.com.

  The targetInfo record was returned by the target and it's stored in
  position 1 in the result set, z.1. To retrieve the whole record we
  must use


       z.1 getExplain 1



  and we get in return



  {targetInfo commonInfo {name {Lucent Technologies Research Server}}
  recentNews icon {namedResultSets 1} {multipleDBsearch 0}
  {maxResultSets 100} {maxResultSize 600000} maxTerms timeoutInterval
  {welcomeMessage {strings { {language eng}
  {text
  {Salutations - this is Lucent Technologies experimental Z39.50 server.
  No guarentees, but free and unlimited access!}} } } }
  {contactInfo {name {Robert Waldstein}} {description {strings
  { {language eng}
  {text {Librarian system designer - no legal anythings}} } } }
  {address {strings { {language eng} {text {Room 3D-591
  600 Mountain Ave
  Murray Hill
  N.J. USA 07974}} } } } {email wald@lucent.com} {phone {908 582-6171}} }
  description nicknames {usageRest {strings { {language eng}
  {text {None - as long as nonProfit research}} } } } paymentAddr
  {hours {strings { {language eng} {text {Should never be down}} } } }
  dbCombinations addresses commonAccessInfo }



  The targetInfo above indicates the the record is really a targetInfo
  record. The commonInfo, which is optional, is not supplied by this
  server. The name, however is supplied, with the value Lucent
  Technologies Research Server.

  To retrieve the contactInfo from the record above we can extract the
  element from the record by using Tcl's list manipulation facilities,
  for example by doing


       set ti [z.1 getExplain 1]
       lindex [lindex $ti 0] 12



  which will return


       contactInfo {name {Robert Waldstein}} {description {strings
       { {language eng}
       {text {Librarian system designer - no legal anythings}} }
       } } {address {strings { {language eng} {text {Room 3D-591
       600 Mountain Ave
       Murray Hill
       N.J. USA 07974}} } } } {email wald@lucent.com} {phone {908 582-6171}}



  We can also extract almost the same by doing


       z.1 getExplain 1 targetInfo contactInfo



  which will return



  {name {Robert Waldstein}} {description {strings { {language eng}
  {text {Librarian system designer - no legal anythings}} } } }
  {address {strings { {language eng} {text {Room 3D-591
  600 Mountain Ave
  Murray Hill
  N.J. USA 07974}} } } } {email wald@lucent.com} {phone {908 582-6171}}



  End of example


  6.  Scan

  To perform scan, a scan object must be created by the ir-scan command.
  This command has two arguments -- name of the scan object and name of
  the ir object. Basically, the scan object, provides one scan action
  which sends a scan request to the target. The action is followed by a
  string describing starting point of the term list. The format used is
  a simple subset of the query used in search requests. Only @attr
  specifications and simple terms are allowed.  The settings that affect
  the scan are:


     stepSize integer
        Step size. Default is 0.

     numberOfTermsRequested integer
        Number of terms requested. Default is 20.

     preferredPositionInResponse integer
        Preferred position in response. Default is 1.

     databaseNames list
        Database names. Note that this setting is not (yet) supported
        for the scan object. You must set this for the ir object
        instead.

     referenceId string
        Reference-id. If string is empty no reference-id is used.

     scanResponse list
        Scan-response Tcl script.

     callback list
        General response Tcl script. Only used if scanResponse is not
        specified.  This setting is valid only for the ir object -- not
        the ir-set object.

  The scan object normally holds one or more scan line entries upon
  successful completion. The table below summarizes the settings that
  should be used in a response handler.


     scanStatus returns integer
        Scan status. An integer between 0 and 6.

     numberOfTermsReturned returns integer
        Number of terms returned.

     positionOfTerm returns integer
        An integer describing the position of term.

     scanLine returns list
        This function returns information about a given scan line
        (entry) at a given index specified by the integer. The first
        scan line is numbered zero; the second 1 and so on. A list is
        returned by the scanLine setting. The first element is T if the
        scan line is a normal term and SD if the scan line is a
        surrogate diagnostic. In the first case (normal) the scan term
        is second element in the list and the number of occurences is
        the third element.  In the other case (surrogate diagnostic),
        the second element is the diagnostic code, the third a text
        representation of the error code and the fourth element is
        additional information.

     referenceId returns string
        Reference-id of scan response.

  Example

  We will scan for the terms after science in the Title index.  We will
  assume that an ir object called z-assoc has already been created.



          z-assoc callback {scan-response}
          ir-scan z-scan z-assoc
          z-scan scan "@attr 1=4 science"

          proc scan-response {} {
              set status [z-scan status]
              if {$status == 0} {
                  set no [z-scan numberOfTermsReturned]
                  for {set i 0} {$i < $no} {incr i} {
                      set line [z-scan scanLine $i]
                      set type [lindex $line 0]
                      if {$type == "T"} {
                          puts [lindex $line 1]
                      } elseif {$type == "SD"} {
                          puts [lindex $line 1]
                      }
                  }
              }
          }



  End of examle


  7.  License

  Copyright (C) 1995-2001, Index Data ApS.

  Permission to use, copy, modify, distribute, and sell this software
  and its documentation, in whole or in part, for any purpose, is hereby
  granted, provided that:

  1. This copyright and permission notice appear in all copies of the
  software and its documentation. Notices of copyright or attribution
  which appear at the beginning of any file must remain unchanged.

  2. The names of Index Data or the individual authors may not be used
  to endorse or promote products derived from this software without
  specific prior written permission.

  THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,
  EXPRESS, IMPLIED, OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  IN
  NO EVENT SHALL INDEX DATA BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
  INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT
  ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY,
  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  SOFTWARE.


  8.  About Index Data

  Index Data is a consulting and software-development enterprise that
  specialises in library and information management systems. Our
  interests and expertise span a broad range of related fields, and one
  of our primary, long-term objectives is the development of a powerful
  information management system with open network interfaces and
  hypermedia capabilities.

  We make this software available free of charge, on a fairly
  unrestrictive license; as a service to the networking community, and
  to further the development of quality software for open network
  communication.

  We'll be happy to answer questions about the software, and about
  ourselves in general.



       Index Data
       Kobmagergade 43
       1150 Copenhagen K
       Denmark



       Phone: +45 3341 0100
       Fax  : +45 3341 0101
       Email: info@indexdata.dk



  9.  References



     1 IrTcl Homepage
        http://www.indexdata.dk/irtcl/


     2 Ousterhout, John K.:
        Tcl and the Tk Toolkit. Addison-Wesley Company Inc (ISBN
        0-201-63337-X). The Tcl/Tk toolkit home page is
        http://tcl.activestate.com.  The primary download area is
        http://prdownloads.sourceforge.net/tcl/.


     3 Welch, Brent B.:
        Practical Programming in Tcl and Tk. Prentice Hall (ISBN
        0-13-616830-2).



