|
HP OpenVMS systems documentation |
Previous | Contents | Index |
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 HP OpenVMS RTL Library (LIB$) Manual for a complete description of LIB$CREATE_DIR.
24.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; |
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 |
Three routines allow you to manipulate the contents of a balanced binary tree:
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 |