However, the question
asks to check programmatically. Again we turn to the SHOW command, but
instead we use the callable interface to the SHOW command, available from
the S1032_HLI tools library, the SHOW_TEXT procedure. Unfortunately, FILE
is not an available option for the SHOW_TEXT procedure.
So, we will use the
SHOW command, but output the information to memory, then parse out the
portion we are specifically interested in: the current file specification.
To accomplish this,
we will use two tools procedures, found in the S1032_HLI library, available
in the S1032_TOOLS file area. The procedures are INIT_OUTPUT and GET_OUTPUT.
The INIT_OUTPUT procedure
lets you output to a memory channel, and GET_OUTPUT lets you retrieve
data from a memory channel into a variable. The sequence of commands necessary
to extract the currently open datasets file specification into a
variable is:
1032> SHOW DS FILE Dataset FILMS File: SYS$SYSDEVICE:[S1032.V9811.DEMO]FILMS.DMS;4 Typed String: S1032_DEMO: Expanded String: DDSK:[DEMO_DVL.SYS]FILMS.DMS 1032> OPEN LIB S1032_HLI IN S1032_TOOLS READONLY 1032> SHOW PROCEDURE INIT_OUTPUT PARAMETER Procedure INIT_OUTPUT CHANNEL Integer 1032> SHOW PROCEDURE GET_OUTPUT PARAMETER Procedure GET_OUTPUT OUTBUF Output Text OUTPUT_LINES Output Integer CHANNEL Integer NUM_LINES Integer Optional 1032> 1032> VARIABLE flspec TEXT VARYING 1032> VARIABLE nmlines INTEGER 1032> 1032> CALL INIT_OUTPUT(8) Initializing channel 8 1032> SHOW ON CHANNEL 8 DATASET FILE 1032> CALL GET_OUTPUT(flspec,nmlines,8,2) 1032> 1032> WRITE FLSPEC Dataset FILMS File: SYS$SYSDEVICE:[S1032.V9811.DEMO]FILMS.DMS;4 1032> 1032> LET flspec = flspec[$FIND("File:",flspec,1,1)+6:$LEN(flspec)] 1032> WRITE flspec SYS$SYSDEVICE:[S1032.V9811.DEMO]FILMS.DMS;4 1032> RELEASE CHANNEL 8 1032>
|
|
Begin by doing a
SHOW PARAMETER of the procedures to check what must be passed into the
procedures. For the INIT_OUTPUT procedure, we must supply only the channel
number, which does not need to be a variable. I chose channel 8. In contrast,
calls to the GET_OUTPUT procedure do require us to define variables, as
data is passed back, so a text buffer and an integer buffer are declared.
To perform the work,
first initialize a memory channel. Then, use the SHOW command to write
the file information into the memory buffer. Next, a call to the GET_OUTPUT
procedure directs the procedure to read the first two records from channel
8, and return the text data into the text variable. Although it is not
displayed, the nmlines variable contains 2.
Writing out the contents
of the text buffer variable shows the first two lines of the SHOW FILE
output. Since we want only the dataset file specification in the variable,
use the System 1032 substring operator ("[n:m]") to extract
the file specification itself, by positioning to the end of the title
string "File: " using the $FIND system function. The m
value for the substring operator is the current length of the string.
Once we have the
value, release the memory channel in the normal fashion.
I
must generate hundreds of data files from a dataset that will later be
used to create a new copy of a dataset. What are my options to programmatically
create the proper file names from attributes and/or variables? Oh, by
the way, the output data is in binary.
Up to the last aside,
this is a straightforward request. A facility exists just for this sort
of case, the $FILE system function. $FILE lets you pass a text expression
to be used as a file specification.
1032> Variable Filename Text Varying 1032> Let Filename = $Text($Now,D5.5),- Filename = $Repall(":","",Filename),- Filename = $Repall(".","",Filename),- Filename = $Repall(" ","",Filename) 1032> Initialize Channel 8 $File(Filename&".DMI") Initializing channel 8 1032> Write Filename 0602101451510241190
|
|
$FILE,
however, works only with the INITIALIZE command. As the question involves
binary data, the DUMP command is necessary, and the $FILE system function
does not work with the DUMP command.
Historically the
solution is to build the file name into the command via text concatenation.
This is done either in HLI via the DM_EXEC (or DM_CMD) statements, or
via use of the EXECUTE command. For example, in FORTRAN, the file name
is part of the text expression passed.
Filnam = FIN95
Stat = DM_EXEC(DUMP DATA //Filnam//.DMI)
|
|
In a similar fashion,
you can use the EXECUTE command within System 1032 to build command expressions
to run. The problem with using EXECUTE processing is that the command
operates one command level above where it is defined. If you use it within
a procedure, any variables necessary to create the command expression
must be declared outside of the procedure itself, so that EXECUTE processing
can reference them for execution.
Fortunately, a third
method has recently presented itself. In this solution, we make use of
a VMS technology: logical names. By using the SET_LOGICAL tools procedure,
we can define a temporary logical name to represent the file specification
we want to dump data into. The DUMP command specifies the logical name
as the DATA_OUTPUT parameter value. If the logical name is redefined before
the next use of the DUMP command, the output goes into a separately named
file.