 |
HP Fortran for OpenVMS User Manual
- The library module FORIOSDEF must be included
to define the symbolic status codes returned by HP Fortran I/O
statements.
- This program requires a relative file named
REL.DAT.
- The SHARED qualifier is used on the OPEN
statement to indicate that the file can be shared. Because manual
locking was not specified, RMS automatically controls access to the
file. Only read and update operations are allowed in this example. No
new records can be written to the file.
- The second process is not allowed to access
record #2 while the first process is accessing it.
- Once the first process has finished with
record #2, the second process can update it.
F.6 Displaying Data at Terminals
The following example calls SMG routines to format screen output.
No sample run is included for this example because the program requires
a video terminal in order to execute properly.
Source Program:
! File: SMGOUTPUT.F90
!
! This program calls Run-Time Library Screen Management routines
! to format screen output.
IMPLICIT INTEGER (KIND=4) (A-Z)
INCLUDE '($SMGDEF)' (1)
! Establish terminal screen as pasteboard
STATUS = SMG$CREATE_PASTEBOARD (NEW_PID,,,) (2)
IF (.NOT. STATUS) CALL LIB$STOP(%VAL(STATUS))
! Establish a virtual display region
STATUS = SMG$CREATE_VIRTUAL_DISPLAY (15,30,DISPLAY_ID,,,) (3)
IF (.NOT. STATUS) CALL LIB$STOP(%VAL(STATUS))
! Paste the virtual display to the screen, starting at
! row 2, column 15
STATUS = SMG$PASTE_VIRTUAL_DISPLAY(DISPLAY_ID,NEW_PID,2,15) (4)
IF (.NOT. STATUS) CALL LIB$STOP(%VAL(STATUS))
! Put a border around the display area
STATUS = SMG$LABEL_BORDER(DISPLAY_ID,'This is the Border',,,,,) (5)
IF (.NOT. STATUS) CALL LIB$STOP(%VAL(STATUS))
! Write text lines to the screen
STATUS = SMG$PUT_LINE (DISPLAY_ID,' ',,,,,)
IF (.NOT. STATUS) CALL LIB$STOP(%VAL(STATUS))
STATUS = SMG$PUT_LINE (DISPLAY_ID,'Howdy, pardner',2,,,,) (6)
IF (.NOT. STATUS) CALL LIB$STOP(%VAL(STATUS))
STATUS = SMG$PUT_LINE (DISPLAY_ID,'Double spaced lines...',2,,,,) (6)
IF (.NOT. STATUS) CALL LIB$STOP(%VAL(STATUS))
STATUS = SMG$PUT_LINE (DISPLAY_ID,'This line is blinking',2, & (7)
SMG$M_BLINK,0,,)
IF (.NOT. STATUS) CALL LIB$STOP(%VAL(STATUS))
STATUS = SMG$PUT_LINE (DISPLAY_ID,'This line is reverse video',2, & (7)
SMG$M_REVERSE,0,,)
IF (.NOT. STATUS) CALL LIB$STOP(%VAL(STATUS))
DO I = 1, 5 (8)
STATUS = SMG$PUT_LINE (DISPLAY_ID,'Single spaced lines...',,,,,)
IF (.NOT. STATUS) CALL LIB$STOP(%VAL(STATUS))
ENDDO
END PROGRAM
|
- The INCLUDE statement incorporates the
$SMGDEF library module from FORSYSDEF.TLB into the source program. This
library module contains symbol definitions used by the screen
management routines.
- The call to SMG$CREATE_PASTEBOARD creates a
pasteboard upon which output will be written. The pasteboard ID is
returned in the variable NEW_PID.
No value is specified for the
output device parameter, so the output device defaults to SYS$OUTPUT.
Also, no values are specified for the PB_ROWS or PB_COLS parameters, so
the pasteboard is created with the default number of rows and columns.
The defaults are the number of rows and the number of columns on the
physical screen of the terminal to which SYS$OUTPUT is assigned.
- The created virtual display is 15 lines long
and 30 columns wide. The virtual display initially contains blanks.
- The virtual display is pasted to the
pasteboard, with its upper left corner positioned at row 2, column 15
of the pasteboard. Pasting the virtual display to the pasteboard causes
all data written to the virtual display to appear on the pasteboard's
output device, which is SYS$OUTPUT---the terminal screen.
At this
point, nothing appears on the screen because the virtual display
contains only blanks. However, because the virtual display is pasted to
the pasteboard, the program statements described below cause text to be
written to the screen.
- A labeled border is written to the virtual
display.
- Using a call to the RTL routine SMG$PUT_LINE,
the text line ("Howdy, pardner" is written to the virtual
display.
To specify double spacing, a call to SMG$PUT_LINE displays
"Double spaced lines..." by specifying the line-adv (third)
argument to SMG$PUT_LINE as 2.
- Two subsequent calls to SMG$PUT_LINE specify
the SMG$M_BLINK and SMG$M_REVERSE parameters (rendition-set argument)
display the double-spaced lines "This line is blinking" as
blinking and "This line is reverse video" in reverse video.
The parameter mask constants like SMG$M_BLINK are defined in the
$SMGDEF library module in FORSYSDEF.TLB.
- The program displays single-spaced text by
omitting a value for the line-adv argument (third argument) to
SMG$PUT_LINE. The DO loop displays the line "Single spaced
lines..." five times.
F.7 Creating, Accessing, and Ordering Files
In the following example, each record in a relative file is assigned to
a specific cell in that file. On sequential write operations, the
records are written to consecutive empty cells. Random write operations
place the records into cell numbers as provided by the REC=n parameter.
Source Program:
! File: RELATIVE.F90
!
! This program demonstrates how to access a relative file
! randomly. It also performs some I/O status checks.
IMPLICIT INTEGER (KIND=4) (A - Z)
STRUCTURE /EMPLOYEE_STRUC/
CHARACTER(LEN=5) ID_NUM
CHARACTER(LEN=6) NAME
CHARACTER(LEN=3) DEPT
CHARACTER(LEN=2) SKILL
CHARACTER(LEN=4) SALARY
END STRUCTURE
RECORD /EMPLOYEE_STRUC/ EMPLOYEE_REC
INTEGER (KIND=4) REC_LEN
INCLUDE '($FORIOSDEF)' (1)
OPEN (UNIT=1, FILE='REL', STATUS='OLD', ORGANIZATION='RELATIVE', & (2)
ACCESS='DIRECT', FORM='UNFORMATTED',RECORDTYPE='VARIABLE')
! Get records by record number until e-o-f
! Prompt for record number
100 TYPE 10
10 FORMAT ('$Record number: ')
READ (*,*, END=999) REC_NUM (3)
! Read record by record number
READ (1,REC=REC_NUM,IOSTAT=STATUS) EMPLOYEE_REC
! Check I/O status
IF (STATUS .EQ. 0) THEN
WRITE (6) EMPLOYEE_REC (4)
ELSE IF (STATUS .EQ. FOR$IOS_ATTACCNON) THEN
TYPE *, 'Nonexistent record.'
ELSE IF (STATUS .EQ. FOR$IOS_RECNUMOUT) THEN
TYPE *, 'Record number out of range.'
ELSE
CALL ERRSNS (, RMS_STS, RMS_STV,,) (5)
CALL LIB$SIGNAL (%VAL(RMS_STS), %VAL(RMS_STV))
ENDIF
! Loop
GOTO 100
999 END
|
Sample Use:
$ FORTRAN RELATIVE
$ LINK RELATIVE
$ RUN RELATIVE
Record number: 7
08001FLANJE119PL1920
Record number: 1
07672ALBEHA210SE2100
Record number: 30
Nonexistent record.
Record number: Ctrl/Z
$
|
- The INCLUDE statement defines all Fortran I/O
status codes.
- The OPEN statement defines the file and
record processing characteristics. Although the file organization is
specified as relative, RMS would in fact obtain the file organization
from an existing file. If the file's organization were not relative,
the file OPEN statement would fail.
The file is being opened for
unformatted I/O because the data records will be read into an
HP Fortran record (EMPLOYEE_REC), and HP Fortran does not allow
records to be used in formatted I/O.
- The READ statement reads the record specified
in REC_NUM, rather than the next consecutive record. The status code
for the record operation is returned in the variable STATUS.
- These statements test the record operation
status obtained in comment 3. Note, the status codes returned by RMS
and HP Fortran are not numerically or functionally similar.
- RMS status codes actually require two
parameters. These values can be obtained using the ERRSNS subroutine.
F.8 Measuring and Improving Performance
This example demonstrates how to adjust the size of the process working
set from a program.
Source Program:
! File: ADJUST.F90
!
! This program demonstrates how a program can control
! its working set size using the $ADJWSL system service.
IMPLICIT INTEGER (A-Z)
INCLUDE '($SYSSRVNAM)'
INTEGER (KIND=4) ADJUST_AMT /0/
INTEGER (KIND=4) NEW_LIMIT /0/
CALL LIB$INIT_TIMER
DO ADJUST_AMT= -50,70,10
! Modify working set limit
RESULT = SYS$ADJWSL( %VAL(ADJUST_AMT), NEW_LIMIT) (1)
IF (.NOT. RESULT) CALL LIB$STOP(%VAL(RESULT))
TYPE 50, ADJUST_AMT, NEW_LIMIT
50 FORMAT(' Modify working set by', I4, ' New working set size =', I5)
END DO
CALL LIB$SHOW_TIMER
END PROGRAM
|
Sample Use:
$ SET WORKING_SET/NOADJUST (2)
$ SHOW WORKING_SET
Working Set /Limit=2000 /Quota=4000 /Extent=98304
Adjustment disabled Authorized Quota=4000 Authorized Extent=98304
Working Set (8Kb pages) /Limit=125 /Quota=250 /Extent=6144
Authorized Quota=250 Authorized Extent=6144
$ FORTRAN ADJUST
$ LINK ADJUST
$ RUN ADJUST
Modify working set by -50 New working set size = 1936 (3)
Modify working set by -40 New working set size = 1888
Modify working set by -30 New working set size = 1856
Modify working set by -20 New working set size = 1824
Modify working set by -10 New working set size = 1808
Modify working set by 0 New working set size = 1808
Modify working set by 10 New working set size = 1824
Modify working set by 20 New working set size = 1856
Modify working set by 30 New working set size = 1888
Modify working set by 40 New working set size = 1936
Modify working set by 50 New working set size = 2000
Modify working set by 60 New working set size = 2064
Modify working set by 70 New working set size = 2144
ELAPSED: 0 00:00:00.01 CPU: 0:00:00.01 BUFIO: 13 DIRIO: 0 FAULTS: 24
$
|
- The call to SYS$ADJWSL call uses a function
invocation.
- The DCL SHOW WORKING_SET command displays the
current working set limit and the maximum quota.
- The SYS$ADJWSL is used to increase or
decrease the number of pages in the process working set.
The program cannot decrease the working set limit beneath the minimum
established by the operating system, nor can the process working set be
expanded beyond the authorized quota.
F.9 Accessing Help Libraries
The following example demonstrates how to obtain text from a help
library. After the initial help request has been satisfied, the user is
prompted and can request additional information.
Source Program:
! File: HELPOUT.F90
!
! This program satisfies an initial help request and enters interactive
! HELP mode. The library used is SYS$HELP:HELPLIB.HLB.
IMPLICIT INTEGER (KIND=4) (A - Z)
CHARACTER(LEN=32) KEY
EXTERNAL LIB$PUT_OUTPUT,LIB$GET_INPUT (1)
! Request a HELP key
WRITE (6,200)
200 FORMAT(1X,'What Topic would you like HELP with? ',$)
READ (5,100) KEY
100 FORMAT (A32)
! Locate and print the help text
STATUS = LBR$OUTPUT_HELP(LIB$PUT_OUTPUT,,KEY, & (2)
'HELPLIB',,LIB$GET_INPUT)
IF (.NOT. STATUS) CALL LIB$STOP (%VAL(STATUS))
END PROGRAM
|
Sample Use:
$ FORTRAN HELPOUT
$ LINK HELPOUT
$ RUN HELPOUT
What topic would you like HELP with? TYPE
TYPE
Displays the contents of a file or a group of files on the
current output device.
Format:
TYPE file-spec[,...]
Additional information available:
Parameters Qualifiers
/BACKUP /BEFORE /BY_OWNER /CONFIRM /CONTINUOUS /CREATED
/EXACT /EXCLUDE /EXPIRED /HEADER /HIGHLIGHT /MODIFIED /OUTPUT
/PAGE /SEARCH /SINCE /TAIL /WRAP
Examples
TYPE Subtopic? /HIGHLIGHT
TYPE
/HIGHLIGHT
/HIGHLIGHT[=keyword]
/NOHIGHLIGHT (default)
Use with the /PAGE=SAVE and /SEARCH qualifiers to specify the
type of highlighting you want when a search string is found. When
a string is found, the entire line is highlighted. You can use
the following keywords: BOLD, BLINK, REVERSE, and UNDERLINE. BOLD
is the default highlighting.
TYPE Subtopic? Ctrl/Z
$
|
- To pass the address of LIB$PUT_OUTPUT and
LIB$GET_INPUT, they must be declared as EXTERNAL. You can supply your
own routines for handling input and output.
- The address of an output routine is a
required argument. When requesting prompting mode, the default mode, an
input routine must be specified.
F.10 Creating and Managing Other Processes
The following example demonstrates how a created process can use the
SYS$GETJPIW system service to obtain the PID of its creator process. It
also shows how to set up an item list to translate a logical name
recursively.
Source Program:
! File: GETJPI.F90
! This program demonstrates process creation and control.
! It creates a subprocess then hibernates until the subprocess wakes it.
IMPLICIT INTEGER (KIND=4) (A - Z)
INCLUDE '($SSDEF)'
INCLUDE '($LNMDEF)'
INCLUDE '($SYSSRVNAM)'
CHARACTER(LEN=255) TERMINAL /'SYS$OUTPUT'/
CHARACTER(LEN=9) FILE_NAME /'GETJPISUB'/
CHARACTER(LEN=5) SUB_NAME /'OSCAR'/
INTEGER (KIND=4) PROCESS_ID /0/
CHARACTER(LEN=17) TABNAM /'LNM$PROCESS_TABLE'/
CHARACTER(LEN=255) RET_STRING
CHARACTER(LEN=2) ESC_NULL
INTEGER (KIND=4) RET_ATTRIB
INTEGER (KIND=4) RET_LENGTH /10/
STRUCTURE /ITMLST3_3ITEMS/
STRUCTURE ITEM(3)
INTEGER (KIND=2) BUFFER_LENGTH
INTEGER (KIND=2) CODE
INTEGER (KIND=4) BUFFER_ADDRESS
INTEGER (KIND=4) RETLEN_ADDRESS
END STRUCTURE
INTEGER (KIND=4) END_OF_LIST
END STRUCTURE
RECORD /ITMLST3_3ITEMS/ TRNLST
! Translate SYS$OUTPUT
! Set up TRNLST, the item list for $TRNLNM
TRNLST.ITEM(1).CODE = LNM$_STRING
TRNLST.ITEM(1).BUFFER_LENGTH = 255
TRNLST.ITEM(1).BUFFER_ADDRESS = %LOC(RET_STRING)
TRNLST.ITEM(1).RETLEN_ADDRESS = 0
TRNLST.ITEM(2).CODE = LNM$_ATTRIBUTES
TRNLST.ITEM(2).BUFFER_LENGTH = 4
TRNLST.ITEM(2).BUFFER_ADDRESS = %LOC(RET_ATTRIB)
TRNLST.ITEM(2).RETLEN_ADDRESS = 0
TRNLST.ITEM(3).CODE = LNM$_LENGTH
TRNLST.ITEM(3).BUFFER_LENGTH = 4
TRNLST.ITEM(3).BUFFER_ADDRESS = %LOC(RET_LENGTH)
TRNLST.ITEM(3).RETLEN_ADDRESS = 0
TRNLST.END_OF_LIST = 0
! Translate SYS$OUTPUT
100 STATUS = SYS$TRNLNM (,TABNAM,TERMINAL(1:RET_LENGTH),,TRNLST)
IF (.NOT. STATUS) CALL LIB$STOP (%VAL(STATUS))
IF (IAND(LNM$M_TERMINAL, RET_ATTRIB).EQ. 0) THEN
TERMINAL = RET_STRING(1:RET_LENGTH)
GO TO 100
ENDIF
! Check if process permanent file
ESC_NULL(1:2) = char('1B'x)//char('00'x)
IF (RET_STRING(1:2) .EQ. ESC_NULL) THEN
RET_STRING = RET_STRING(5:RET_LENGTH)
RET_LENGTH = RET_LENGTH - 4
ENDIF
! Create the subprocess
STATUS = SYS$CREPRC (PROCESS_ID, FILE_NAME,, & (1)
RET_STRING(1:RET_LENGTH),,,, &
SUB_NAME,%VAL(4),,,)
IF (.NOT. STATUS) CALL LIB$STOP (%VAL(STATUS))
TYPE 10, PROCESS_ID
10 FORMAT (' PID of subprocess OSCAR is ', Z)
! Wait for wakeup by subprocess
STATUS = SYS$HIBER () (2)
IF (.NOT. STATUS) CALL LIB$STOP (%VAL(STATUS))
TYPE *, 'GETJPI has been awakened.'
END PROGRAM
! File: GETJPISUB.F90
! This separately compiled program is run in the subprocess OSCAR
! which is created by GETJPI. It obtains its creator's PID and then
! wakes it.
IMPLICIT INTEGER (KIND=4) (A - Z) (3)
INCLUDE '($JPIDEF)'
INCLUDE '($SYSSRVNAM)'
STRUCTURE /GETJPI_IOSB/
INTEGER(KIND=4) STATUS
INTEGER(KIND=4) %FILL
END STRUCTURE
RECORD /GETJPI_IOSB/ IOSB
STRUCTURE /ITMLST3_1ITEM/
STRUCTURE ITEM
INTEGER (KIND=2) BUFFER_LENGTH
INTEGER (KIND=2) CODE
INTEGER (KIND=4) BUFFER_ADDRESS
INTEGER (KIND=4) RETLEN_ADDRESS
END STRUCTURE
INTEGER (KIND=4) END_OF_LIST
END STRUCTURE
RECORD /ITMLST3_1ITEM/ JPI_LIST
! Set up buffer address for GETJPI
JPI_LIST.ITEM.CODE = JPI$_OWNER (4)
JPI_LIST.ITEM.BUFFER_LENGTH = 4
JPI_LIST.ITEM.BUFFER_ADDRESS = %LOC(OWNER_PID)
JPI_LIST.ITEM.RETLEN_ADDRESS = 0
! Get PID of creator
STATUS = SYS$GETJPIW (%VAL(1),,, JPI_LIST,IOSB,,) (5)
IF (.NOT. STATUS) CALL LIB$STOP (%VAL(STATUS))
IF (.NOT. IOSB.STATUS) CALL LIB$STOP (%VAL(IOSB.STATUS))
! Wake creator
TYPE *, 'OSCAR is waking creator.'
STATUS = SYS$WAKE (OWNER_PID,)
IF (.NOT. STATUS) CALL LIB$STOP (%VAL(STATUS))
END PROGRAM
|
Sample Use:
$ FORTRAN GETJPI,GETJPISUB
$ LINK GETJPI
$ LINK GETJPISUB
$ RUN GETJPI
PID of subprocess OSCAR is 2120028A
OSCAR is waking creator.
GETJPI has been awakened.
|
- The subprocess is created using SYS$CREPRC.
- The process hibernates.
- The INCLUDE statement defines the value of
all JPI$ codes including JPI$_OWNER. JPI$_OWNER is the item code which
requests the PID of the owner process. If there is no owner process
(that is, if the process about which information is requested is a
detached process), the system service $GETJPIW returns a PID of zero.
- Because of the item code JPI$_OWNER in the
item list, $GETJPIW returns the PID of the owner of the process about
which information is requested. If the item code were JPI$_PID,
$GETJPIW would return the PID of the process about which information is
requested.
Because the default value of 0 is used for arguments
PIDADR and PRCNAM, the process about which information is requested is
the requesting process, namely, OSCAR.
- The item list for SYS$GETJPIW consists of a
single item descriptor followed by a zero longword.
|