Document revision date: 19 July 1999
[Compaq] [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]
[OpenVMS documentation]

OpenVMS Programming Concepts Manual


Previous Contents Index

7.7 Miscellaneous Interface Routines

There are several other RTL routines that permit high-level access to components of the operating system. Table 7-12 lists these routines and their functions. The sections that follow give further details about some of these routines.

Table 7-12 Miscellaneous Interface Routines
Entry Point Function
LIB$AST_IN_PROG Indicates whether an asynchronous system trap is in progress
LIB$ASN_WTH_MBX Assigns an I/O channel and associates it with a mailbox
LIB$CREATE_DIR Creates a directory or subdirectory
LIB$FIND_IMAGE_SYMBOL Reads a global symbol from the shareable image file and dynamically activates a shareable image into the P0 address space of a process
LIB$ADDX Performs addition on signed two's complement integers of arbitrary length (multiple-precision addition)
LIB$SUBX Performs subtraction on signed two's complement integers of arbitrary length (multiple-precision subtraction)
LIB$FILE_SCAN Finds file names given OpenVMS RMS file access block (FAB)
LIB$FILE_SCAN_END End-of-file scan
LIB$FIND_FILE Finds file names given string
LIB$FIND_FILE_END End-of-find file
LIB$INSERT_TREE Inserts an element in a binary tree
LIB$LOOKUP_TREE Finds an element in a binary tree
LIB$TRAVERSE_TREE Traverses a binary tree
LIB$GET_COMMON Gets a record from the process's COMMON storage area
LIB$PUT_COMMON Puts a record to the process's COMMON storage area

7.7.1 Indicating Asynchronous System Trap in Progress

An asynchronous system trap (AST) is a mechanism for providing a software interrupt when an external event occurs, such as when a user presses the Ctrl/C key sequence. When an external event occurs, the operating system interrupts the execution of the current process and calls a routine that you supply. While that routine is active, the AST is said to be in progress, and the process is said to be executing at AST level. When your AST routine returns control to the original process, the AST is no longer active and execution continues where it left off.

The LIB$AST_IN_PROG routine indicates to the calling program whether an AST is currently in progress. Your program can call LIB$AST_IN_PROG to determine whether it is executing at AST level, and then take appropriate action. This routine is useful if you are writing AST-reentrant code.

For information about using ASTs, see Chapter 5.

7.7.2 Create a Directory or Subdirectory

The LIB$CREATE_DIR routine creates a directory or a subdirectory. The calling program must specify the directory specification in standard OpenVMS RMS format. This directory specification may also contain a disk specification.

In addition to the required directory specification argument, LIB$CREATE_DIR takes the following five optional arguments:

See the OpenVMS RTL Library (LIB$) Manual for a complete description of LIB$CREATE_DIR.

7.7.3 File Searching Routines

The run-time library provides two routines that your program can call to search for a file and two routines that your program can call to end a search sequence.

In addition to the wildcard file specification, which is a required argument, LIB$FIND_FILE takes the following four optional arguments:

The LIB$FIND_FILE_END routine is called once after each call to LIB$FIND_FILE in interactive use. LIB$FIND_FILE_END prevents the temporary default values retained by the previous call to LIB$FIND_FILE from affecting the next file specification.

The LIB$FILE_SCAN routine uses an optional context argument to perform temporary defaulting for multiple input files. For example, a command such as the following would specify A, B, and C in successive calls, retaining context, so that portions of one file specification would affect the next file specification:


$ COPY  [smith]A,B,C * 

The LIB$FILE_SCAN_END routine is called once after each sequence of calls to LIB$FILE_SCAN. LIB$FILE_SCAN_END performs a parse of the null string to deallocate saved OpenVMS RMS context and to prevent the temporary default values retained by the previous call to LIB$FILE_SCAN from affecting the next file specification. For instance, in the previous example, LIB$FILE_SCAN_END should be called after the C file specification is parsed, so that specifications from the $COPY files do not affect file specifications in subsequent commands.

The following BLISS example illustrates the use of LIB$FIND_FILE. It prompts for a file specification and default specification. The default specification indicates the default information for the file for which you are searching. Once the routine has searched for one file, the resulting file specification determines both the related file specification and the default file specification for the next search. LIB$FIND_FILE_END is called at the end of the following BLISS program to deallocate the virtual memory used by LIB$FIND_FILE.


 
%TITLE 'FILE_EXAMPLE1 - Sample program using LIB$FIND_FILE' 
MODULE FILE_EXAMPLE1(           ! Sample program using LIB$FIND_FILE 
                IDENT = '1-001', 
                MAIN = EXAMPLE_START 
                ) = 
BEGIN 
 
%SBTTL 'Declarations' 
!+ 
! SWITCHES: 
!- 
 
SWITCHES ADDRESSING_MODE (EXTERNAL = GENERAL, NONEXTERNAL = WORD_RELATIVE); 
 
!+ 
! TABLE OF CONTENTS: 
!- 
 
FORWARD ROUTINE 
    EXAMPLE_START;                              ! Main program 
 
!+ 
! INCLUDE FILES: 
!- 
 
LIBRARY 'SYS$LIBRARY:STARLET.L32';              ! System symbols 
 
!+ 
! Define facility-specific messages from shared system messages. 
!- 
$SHR_MSGDEF(CLI,3,LOCAL, 
                (PARSEFAIL,WARNING)); 
!+ 
! EXTERNAL REFERENCES: 
!- 
 
EXTERNAL ROUTINE 
    LIB$GET_INPUT,                             ! Read from SYS$INPUT 
    LIB$FIND_FILE,                             ! Wildcard scanning routine 
    LIB$FIND_FILE_END,          ! End find file 
    LIB$PUT_OUTPUT,                            ! Write to SYS$OUTPUT 
    STR$COPY_DX;                               ! String copier 
 
LITERAL 
    TRUE = 1,                                  ! Success 
    FALSE = 0;                                 ! Failure 
 
%SBTTL 'EXAMPLE_START - Sample program main routine'; 
ROUTINE EXAMPLE_START = 
BEGIN 
!+ 
! This program reads a file specification and default file 
! specification from SYS$INPUT.  It then prints all the files that 
! match that specification and prompts for another file specification. 
! After the first file specification no default specification is requested, 
! and the previous resulting file specification becomes the related 
! file specification. 
!- 
LOCAL 
    LINEDESC : $BBLOCK[DSC$C_S_BLN],     ! String desc. for input line 
    RESULT_DESC : $BBLOCK[DSC$C_S_BLN],  ! String desc. for result file 
    CONTEXT,                             ! LIB$FIND_FILE context pointer 
    DEFAULT_DESC : $BBLOCK[DSC$C_S_BLN], ! String desc. for default spec 
    RELATED_DESC : $BBLOCK[DSC$C_S_BLN], ! String desc. for related spec 
    HAVE_DEFAULT, 
    STATUS; 
!+ 
! Make all string descriptors dynamic. 
!- 
CH$FILL(0,DSC$C_S_BLN,LINEDESC); 
LINEDESC[DSC$B_CLASS] = DSC$K_CLASS_D; 
CH$MOVE(DSC$C_S_BLN,LINEDESC,RESULT_DESC); 
CH$MOVE(DSC$C_S_BLN,LINEDESC,DEFAULT_DESC); 
CH$MOVE(DSC$C_S_BLN,LINEDESC,RELATED_DESC); 
HAVE_DEFAULT = FALSE; 
CONTEXT = 0; 
!+ 
! Read file specification, default file specification, and 
! related file specification. 
!- 
 
WHILE (STATUS = LIB$GET_INPUT(LINEDESC, 
                $DESCRIPTOR('FILE SPECIFICATION: '))) NEQ RMS$_EOF 
DO BEGIN 
    IF NOT .STATUS 
        THEN SIGNAL_STOP(.STATUS); 
    !+ 
    ! If default file specification was not obtained, do so now. 
    !- 
    IF NOT .HAVE_DEFAULT 
    THEN BEGIN 
        STATUS = LIB$GET_INPUT(DEFAULT_DESC, 
                $DESCRIPTOR('DEFAULT FILE SPECIFICATION: ')); 
        IF NOT .STATUS 
            THEN SIGNAL_STOP(.STATUS); 
        HAVE_DEFAULT = TRUE; 
        END; 
    !+ 
    ! CALL LIB$FIND_FILE until RMS$_NMF (no more files) is returned. 
    ! If an error other than RMS$_NMF is returned, it is signaled. 
    ! Print out the file specification if the call is successful. 
    !- 
    WHILE (STATUS = LIB$FIND_FILE(LINEDESC,RESULT_DESC,CONTEXT, 
                        DEFAULT_DESC,RELATED_DESC)) NEQ RMS$_NMF 
    DO IF NOT .STATUS 
        THEN SIGNAL(CLI$_PARSEFAIL,1,RESULT_DESC,.STATUS) 
        ELSE LIB$PUT_OUTPUT(RESULT_DESC); 
    !+ 
    ! Make this resultant file specification the related file 
    ! specification for next file. 
    !- 
    STR$COPY_DX(RELATED_DESC,LINEDESC); 
    END;                                    ! End of loop 
                                            !  reading file specification 
 
!+ 
! Call LIB$FIND_FILE_END to deallocate the virtual memory used by LIB$FIND_FILE. 
! Note that we do this outside of the loop.  Since the MULTIPLE bit of the 
! optional user flags argument to LIB$FIND_FILE wasn't used, it is not 
! necessary to call LIB$FIND_FILE_END after each call to LIB$FIND_FILE. 
! (The MULTIPLE bit would have caused temporary defaulting for multiple input 
!  files.) 
!- 
STATUS = LIB$FIND_FILE_END (CONTEXT); 
 
IF NOT .STATUS 
    THEN SIGNAL_STOP (.STATUS); 
 
RETURN TRUE 
END;                                        ! End of main program 
END                                         ! End of module 
 
ELUDOM 
 
 

The following BLISS example illustrates the use of LIB$FILE_SCAN and LIB$FILE_SCAN_END.


 
%TITLE 'FILE_EXAMPLE2 - Sample program using LIB$FILE_SCAN' 
MODULE FILE_EXAMPLE1(             ! Sample program using LIB$FILE_SCAN 
        IDENT = '1-001', 
        MAIN = EXAMPLE_START 
        ) = 
BEGIN 
 
%SBTTL 'Declarations' 
!+ 
! SWITCHES: 
!- 
 
SWITCHES ADDRESSING_MODE (EXTERNAL = GENERAL, 
        NONEXTERNAL = WORD_RELATIVE); 
 
!+ 
! TABLE OF CONTENTS: 
!- 
 
FORWARD ROUTINE 
    EXAMPLE_START,          ! Main program 
    SUCCESS_RTN,            ! Success action routine 
    ERROR_RTN;              ! Error action routine 
 
!+ 
! INCLUDE FILES: 
!- 
 
LIBRARY 'SYS$LIBRARY:STARLET.L32';      ! System symbols 
 
!+ 
! Define VMS block structures (BLOCK[,BYTE]). 
!- 
STRUCTURE 
    BBLOCK [O, P, S, E; N] = 
                [N] 
                (BBLOCK + O) <P, S, E>; 
!+ 
! EXTERNAL REFERENCES: 
!- 
 
EXTERNAL ROUTINE 
    LIB$GET_INPUT,             ! Read from SYS$INPUT 
    LIB$FILE_SCAN,             ! Wildcard scanning routine 
    LIB$FILE_SCAN_END,         ! End of file scan 
    LIB$PUT_OUTPUT;            ! Write to SYS$OUTPUT 
 
%SBTTL 'EXAMPLE_START - Sample program main routine'; 
ROUTINE EXAMPLE_START = 
BEGIN 
!+ 
! This program reads the file specification, default file specification, 
! and related file specification from SYS$INPUT and then displays on 
! SYS$OUTPUT all files which match the specification. 
!- 
LOCAL 
    RESULT_BUFFER : VECTOR[NAM$C_MAXRSS,BYTE], !Buffer for resultant 
                                               !  name string 
    EXPAND_BUFFER : VECTOR[NAM$C_MAXRSS,BYTE], !Buffer for expanded 
                                               !  name string 
    LINEDESC : BBLOCK[DSC$C_S_BLN],            !String descriptor 
                                               !  for input line 
    RESULT_DESC : BBLOCK[DSC$C_S_BLN],         !String descriptor 
                                               !  for result file 
    DEFAULT_DESC : BBLOCK[DSC$C_S_BLN],        !String descriptor 
                                               !  for default specification 
    RELATED_DESC : BBLOCK[DSC$C_S_BLN],        !String descriptor 
                                               !  for related specification 
    IFAB : $FAB_DECL,                          !FAB for file_scan 
    INAM : $NAM_DECL,                          !  and a NAM block 
    RELNAM : $NAM_DECL,                        !  and a related NAM block 
    STATUS; 
!+ 
! Make all descriptors dynamic. 
!- 
CH$FILL(0,DSC$C_S_BLN,LINEDESC); 
LINEDESC[DSC$B_CLASS] = DSC$K_CLASS_D; 
CH$MOVE(DSC$C_S_BLN,LINEDESC,RESULT_DESC); 
CH$MOVE(DSC$C_S_BLN,LINEDESC,DEFAULT_DESC); 
CH$MOVE(DSC$C_S_BLN,LINEDESC,RELATED_DESC); 
!+ 
! Read file specification, default file specification, and related 
! file specification 
!- 
STATUS = LIB$GET_INPUT(LINEDESC, 
                $DESCRIPTOR('File specification: ')); 
IF NOT .STATUS 
    THEN SIGNAL_STOP(.STATUS); 
STATUS = LIB$GET_INPUT(DEFAULT_DESC, 
                $DESCRIPTOR('Default file specification: ')); 
IF NOT .STATUS 
    THEN SIGNAL_STOP(.STATUS); 
STATUS = LIB$GET_INPUT(RELATED_DESC, 
                $DESCRIPTOR('Related file specification: ')); 
IF NOT .STATUS 
    THEN SIGNAL_STOP(.STATUS); 
!+ 
! Initialize the FAB, NAM, and related NAM blocks. 
!- 
$FAB_INIT(FAB=IFAB, 
        FNS=.LINEDESC[DSC$W_LENGTH], 
        FNA=.LINEDESC[DSC$A_POINTER], 
        DNS=.DEFAULT_DESC[DSC$W_LENGTH], 
        DNA=.DEFAULT_DESC[DSC$A_POINTER], 
        NAM=INAM); 
 
$NAM_INIT(NAM=INAM, 
        RSS=NAM$C_MAXRSS, 
        RSA=RESULT_BUFFER, 
        ESS=NAM$C_MAXRSS, 
        ESA=EXPAND_BUFFER, 
        RLF=RELNAM); 
 
$NAM_INIT(NAM=RELNAM); 
RELNAM[NAM$B_RSL] = .RELATED_DESC[DSC$W_LENGTH]; 
RELNAM[NAM$L_RSA] = .RELATED_DESC[DSC$A_POINTER]; 
!+ 
! Call LIB$FILE_SCAN.  Note that errors need not be checked 
! here because LIB$FILE_SCAN calls error_rtn for all errors. 
!- 
LIB$FILE_SCAN(IFAB,SUCCESS_RTN,ERROR_RTN); 
 
!+ 
! Call LIB$FILE_SCAN_END to deallocate virtual memory used for 
! file scan structures. 
!- 
STATUS = LIB$FILE_SCAN_END (IFAB); 
 
IF NOT .STATUS 
    THEN SIGNAL_STOP (.STATUS); 
 
RETURN 1 
END;                                                ! End of main program 
 
ROUTINE SUCCESS_RTN (IFAB : REF BBLOCK) = 
BEGIN 
!+ 
! This routine is called by LIB$FILE_SCAN for each file that it 
! successfully finds in the search sequence. 
! 
! Inputs: 
! 
!        IFAB    Address of a fab 
! 
! Outputs: 
! 
!        file specification printed on SYS$OUTPUT 
!- 
LOCAL 
    DESC : BBLOCK[DSC$C_S_BLN];    ! A local string descriptor 
BIND 
    INAM = .IFAB[FAB$L_NAM] : BBLOCK;    ! Find NAM block 
                                         !   from pointer in FAB 
CH$FILL(0,DSC$C_S_BLN,DESC);             ! Make static 
                                         !   string descriptor 
DESC[DSC$W_LENGTH] = .INAM[NAM$B_RSL];   ! Get string length 
                                         !   from NAM block 
DESC[DSC$A_POINTER] = .INAM[NAM$L_RSA];  ! Get pointer to the string 
RETURN LIB$PUT_OUTPUT(DESC)              ! Print name on SYS$OUTPUT 
                                         !   and return 
END; 
 
ROUTINE ERROR_RTN (IFAB : REF BBLOCK) = 
BEGIN 
!+ 
! This routine is called by LIB$FILE_SCAN for each file specification that 
! produces an error. 
! 
! Inputs: 
! 
!        ifab     Address of a fab 
! 
! Outputs: 
! 
!        Error message is signaled 
!- 
LOCAL 
    DESC : BBLOCK[DSC$C_S_BLN];            ! A local string descriptor 
 
BIND 
    INAM = .IFAB[FAB$L_NAM] : BBLOCK;      ! Get NAM block pointer 
                                           !   from FAB 
 
CH$FILL(0,DSC$C_S_BLN,DESC);               ! Create static 
                                           !   string descriptor 
DESC[DSC$W_LENGTH] = .INAM[NAM$B_RSL]; 
DESC[DSC$A_POINTER] = .INAM[NAM$L_RSA]; 
!+ 
! Signal the error using the shared message PARSEFAIL 
! and the CLI facility code.  The second part of the SIGNAL 
! is the RMS STS and STV error codes. 
!- 
RETURN SIGNAL((SHR$_PARSEFAIL+3^16),1,DESC, 
                .IFAB[FAB$L_STS],.IFAB[FAB$L_STV]) 
 
END; 
END                   ! End of module 
 
ELUDOM 
 
 

7.7.4 Inserting an Entry into a Balanced Binary Tree

Three routines allow you to manipulate the contents of a balanced binary tree:

Example

The following BLISS example illustrates all three routines. The program prompts for input from SYS$INPUT and stores each data line as an entry in a binary tree. When the user enters the end-of-file character (Ctrl/Z), the tree is printed in sorted order. The program includes three subroutines:


 
%TITLE 'TREE_EXAMPLE   - Sample program using binary tree routines' 
MODULE TREE_EXAMPLE(                      ! Sample program using trees 
                IDENT = '1-001', 
                MAIN = TREE_START 
                ) = 
BEGIN 
 
%SBTTL 'Declarations' 
!+ 
! SWITCHES: 
!- 
SWITCHES ADDRESSING_MODE (EXTERNAL = GENERAL, NONEXTERNAL = WORD_RELATIVE); 
 
!+ 
! LINKAGES: 
! 
!      NONE 
! 
! TABLE OF CONTENTS: 
!- 
 
FORWARD ROUTINE 
    TREE_START,                     ! Main program 
    ALLOC_NODE,                     ! Allocate memory for a node 
    COMPARE_NODE,                   ! Compare two nodes 
    PRINT_NODE;                     ! Print a node (action routine 
                                    !  for LIB$TRAVERSE_TREE) 
 
!+ 
! INCLUDE FILES: 
!- 
 
LIBRARY 'SYS$LIBRARY:STARLET.L32';              ! System symbols 
 
!+ 
! Define VMS block structures (BLOCK[,BYTE]). 
!- 
STRUCTURE 
    BBLOCK [O, P, S, E; N] = 
                [N] 
                (BBLOCK + O) <P, S, E>; 
!+ 
! MACROS: 
!- 
MACRO 
    NODE$L_LEFT = 0,0,32,0%,         ! Left subtree pointer in node 
    NODE$L_RIGHT = 4,0,32,0%,        ! Right subtree pointer 
    NODE$W_BAL = 8,0,16,0%,          ! Balance this node 
    NODE$B_NAMLNG = 10,0,8,0%,       ! Length of name in this node 
    NODE$T_NAME = 11,0,0,0%;         ! Start of name (variable length) 
 
LITERAL 
    NODE$C_LENGTH = 11;              ! Length of fixed part of node 
 
!+ 
! EXTERNAL REFERENCES: 
!- 
 
EXTERNAL ROUTINE 
    LIB$GET_INPUT,                   ! Read from SYS$INPUT 
    LIB$GET_VM,                      ! Allocate virtual memory 
    LIB$INSERT_TREE,                 ! Insert into binary tree 
    LIB$LOOKUP_TREE,                 ! Lookup in binary tree 
    LIB$PUT_OUTPUT,                  ! Write to SYS$OUTPUT 
    LIB$TRAVERSE_TREE,               ! Traverse a binary tree 
    STR$UPCASE,                      ! Convert string to all uppercase 
    SYS$FAO;                         ! Formatted ASCII output routine 
 
%SBTTL 'TREE_START - Sample program main routine'; 
ROUTINE TREE_START = 
BEGIN 
!+ 
! This program reads from SYS$INPUT and stores each data line 
! as an entry in a binary tree.  When end-of-file character (CTRL/Z) 
! is entered, the tree will be printed in sorted order. 
!- 
LOCAL 
    NODE : REF BBLOCK,              ! Address of allocated node 
    TREEHEAD,                       ! List head of binary tree 
    LINEDESC : BBLOCK[DSC$C_S_BLN], ! String descriptor for input line 
    STATUS; 
 
TREEHEAD = 0;                           ! Zero binary tree head 
CH$FILL(0,DSC$C_S_BLN,LINEDESC);        ! Make a dynamic descriptor 
LINEDESC[DSC$B_CLASS] = DSC$K_CLASS_D;  ! ... 
!+ 
! Read input lines until end of file seen. 
!- 
WHILE (STATUS = LIB$GET_INPUT(LINEDESC,           ! Read input line 
                        $DESCRIPTOR('Text: ')))   !  with this prompt 
                NEQ RMS$_EOF 
DO IF NOT .STATUS                            ! Report any errors found 
        THEN SIGNAL(.STATUS) 
        ELSE BEGIN 
            STR$UPCASE(LINEDESC,LINEDESC);   ! Convert string 
                                             !  to uppercase 
            IF NOT (STATUS = LIB$INSERT_TREE( 
                        TREEHEAD,       ! Insert good data into the tree 
                        LINEDESC,       ! Data to insert 
                        %REF(1),        ! Insert duplicate entries 
                        COMPARE_NODE,   ! Addr. of compare routine 
                        ALLOC_NODE,     ! Addr. of node allocation routine 
                        NODE,           ! Return addr. of 
                        0))             !   allocated node here 
                THEN SIGNAL(.STATUS); 
            END; 
!+ 
! End of file character encountered.  Print the whole tree and exit. 
!- 
IF NOT (STATUS = LIB$TRAVERSE_TREE( 
                        TREEHEAD,       ! Listhead of tree 
                        PRINT_NODE,     ! Action routine to print a node 
                        0)) 
    THEN SIGNAL(.STATUS); 
 
RETURN SS$_NORMAL 
END;                                     ! End of routine tree_start 
 
ROUTINE ALLOC_NODE (KEYDESC,RETDESC,CONTEXT) = 
BEGIN 
!+ 
! This routine allocates virtual memory for a node. 
! 
! INPUTS: 
! 
!      KEYDESC                Address of string descriptor for key 
!                              (this is the linedesc argument passed 
!                              to LIB$INSERT_TREE) 
!      RETDESC                Address of location to return address of 
!                              allocated memory 
!      CONTEXT                Address of user context argument passed 
!                              to LIB$INSERT_TREE (not used in this 
!                              example) 
! 
! OUTPUTS: 
! 
!        Memory address returned in longword pointed to by retdesc 
!- 
MAP 
    KEYDESC : REF BBLOCK, 
    RETDESC : REF VECTOR[,LONG]; 
 
LOCAL 
    NODE : REF BBLOCK, 
    STATUS; 
 
STATUS = LIB$GET_VM(%REF(NODE$C_LENGTH+.KEYDESC[DSC$W_LENGTH]),NODE); 
IF NOT .STATUS 
    THEN RETURN .STATUS 
    ELSE BEGIN 
        NODE[NODE$B_NAMLNG] = .KEYDESC[DSC$W_LENGTH];  ! Set name length 
        CH$MOVE(.KEYDESC[DSC$W_LENGTH],                ! Copy in the name 
                .KEYDESC[DSC$A_POINTER], 
                NODE[NODE$T_NAME]); 
        RETDESC[0] = .NODE;                    ! Return address to caller 
        END; 
RETURN .STATUS 
 
END; 
 
 
ROUTINE COMPARE_NODE (KEYDESC,NODE,CONTEXT) = 
BEGIN 
!+ 
! This routine compares a key with a node. 
! 
! INPUTS: 
! 
!       KEYDESC           Address of string descriptor for new key 
!                          (This is the linedesc argument passed to 
!                          LIB$INSERT_TREE) 
!       NODE              Address of current node 
!       CONTEXT           User context data (Not used in this example) 
!- 
MAP 
    KEYDESC : REF BBLOCK, 
    NODE : REF BBLOCK; 
 
RETURN CH$COMPARE(.KEYDESC[DSC$W_LENGTH],          ! Compare key with 
                                                   !  current node 
                        .KEYDESC[DSC$A_POINTER], 
                        .NODE[NODE$B_NAMLNG], 
                        NODE[NODE$T_NAME]) 
 
END; 
 
ROUTINE PRINT_NODE (NODE,CONTEXT) = 
BEGIN 
!+ 
! This routine is called during the tree traversal.  It 
! prints out the left and right subtree pointers, the 
! current node balance, and the name of the node. 
!- 
MAP 
    NODE : REF BBLOCK; 
 
LOCAL 
    OUTBUF : BBLOCK[512],                   ! FAO output buffer 
    OUTDESC : BBLOCK[DSC$C_S_BLN],          ! Output buffer descriptor 
    STATUS; 
CH$FILL(0,DSC$C_S_BLN,OUTDESC);             ! Zero descriptor 
OUTDESC[DSC$W_LENGTH] = 512; 
OUTDESC[DSC$A_POINTER] = OUTBUF; 
IF NOT (STATUS = SYS$FAO($DESCRIPTOR('!XL !XL !XL !XW !AC'), 
                        OUTDESC,OUTDESC, 
                        .NODE,.NODE[NODE$L_LEFT], 
                        .NODE[NODE$L_RIGHT], 
                        .NODE[NODE$W_BAL], 
                        NODE[NODE$B_NAMLNG])) 
    THEN SIGNAL(.STATUS) 
    ELSE BEGIN 
        STATUS = LIB$PUT_OUTPUT(OUTDESC);      ! Output the line 
        IF NOT .STATUS 
            THEN SIGNAL(.STATUS); 
        END; 
 
RETURN SS$_NORMAL 
 
END; 
END                                       ! End of module TREE_EXAMPLE 
 
ELUDOM 
 
 
 


Previous Next Contents Index

  [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]  
  privacy and legal statement  
5841PRO_021.HTML