UREAD is the name of a collection of FORTRAN subroutines designed to
standardize and enhance control input to terminal based interactive
FORTRAN programs. UREAD provides a self documenting method for
creating scripts for automation of interactive programs.
From the applications point of view, a typical use of UREAD looks
like:
CALL UREAD('enter integer:$$')
I=IDCOD(IER)
This code sends the prompt "enter integer:" to the terminal (if
connected) and decodes the response as integer. Many other decoding
formats are available.
In addition to returning decoded information to the calling program,
UREAD supports many special functions, some of which are listed here:
o complete support of typeahead functionality. Input is through
a typeahead buffer. This allows the expert user to anticipate
and answer several program prompts in a single line of input.
UREAD prompting is turned off until the buffer is empty (all
data has been supplied to the application).
o command line arguments, supplied when the interactive program
is activated, are interpreted as responses to the earliest
program prompts.
o transfer of program control to an indirect input file. Indirect
input files (scripts) may invoke further scripts; nine levels of
nesting are supported.
o scripts support a syntax for variable "parameters". Parameter
substitution, arithmetic, branching and looping are allowed.
These features permit UREAD programs to be used interactively, with
partial automation, or entirely in batch, at the user's discretion.
Last review of this documentation: D. McCune 19 Mar 2004.
UREAD documentation frequently refers to "indirect input files".
These are really control scripts, which have a generic format
;<program prompt>$
answer...
;<program prompt #2>$
answer#2...
The documentation refers to "typeahead". This is meant to describe
UREAD's organization of program input into "words", each of which
answers one program prompt. If N words are given in response to
a single prompt, then that prompt is answered, and the following
(N-1) prompts are answered as well. For example, the two scripts
(for a hypothetical program PROG) have the same effect:
script#1:
;PROG: ENTER INTERGER:$
15
;PROG: ENTER FLOATING POINT NUMBER:$
3.14159
;PROG: ENTER CHARACTER STRING:$
"this is a string"
script#2:
;PROG: ENTER INTERGER:$
15 3.14159 "this is a string"
The latter script answers PROG's first three prompts in a single
line. This is a typical use of UREAD's "typeahead" feature.
"Words" are delimited by whitespace or commas. To have a string
containing imbedded blanks counted as one word, the whole string
must be enclosed in double quotes, as in the example just shown.
The error message "UREAD PROMPT MISMATCH/ COMMAND OUT OF SEQUENCE"
and associated information indicates that the prerecorded prompts in
a UREAD format indirect input file do not match the prompts sent
from the executing program. File control is suspended until a
matching prompt is found.
This usually occurs when there is an error in the UREAD-driven
program, which is not explicitly handled by code in the UREAD
driver script. For example, the script might contain a parameter
that asks for a plasma shot number or TRANSP runid; if an invalid
value is specified, the shot or run might not be found.
For detailed information, see the descriptions of the user interface,
specifically the information on UREAD files.
In this section the UREAD - user interface is described. Contents:
(suggestion-- read in the order listed if material is new to you)
HISTORY - where UREAD came from
BENEFITS - how use of UREAD may benefit an application program.
FUNCTION - outline of what UREAD does.
EXECUTION - how to run a UREAD program.
TYPEAHEAD - the UREAD typeahead buffer
COMMANDS - UREAD commands (e.g. *H for HELP, this file).
PARAMETERS - definition and use of UREAD string parameters.
FILES - creation and use of UREAD indirect input files.
BRANCHING - modifying control flow in UREAD indirect input file.
This includes creating "loops".
[author - D. McCune]
I wrote the first version of UREAD in 1980 at PPPL on the PLT/PDX
DAS DEC-10, in FORTRAN IV. An old version on that system was once
used extensively for controlling programs to plot and smooth
experimental input data for the TRANSP analysis code-- from the
PLT and PDX tokamaks, which operated at Princeton in the late 1970s
and early 1980s.
The system was originally intended to localize solutions to
problems associated with the FORTRAN formatted READ or ACCEPT state-
ments (e.g. I could not remember what arbitrary thing a given "E"
format would do to the decimal point of a given floating point input).
However, when all my programs' READ statements were replaced with
UREAD calls I realized that opportunities to do more were at hand.
The system moved to the "HLDAS" VAX-780 in 1980-1981 and has been
growing ever since. Many of the system's features were inspired by
VAX/VMS DCL.
UREAD is used in all interactive routines described in the UFILES
manual-- i.e. all UFILES utilities as well as graphics interface
and smoothing routines (e.g. GRF3F1, USMOO1, etc.) described therein.
It is used in the TRANSP plotting program RPLOT and most other user-
interactive terminal based programs that I have written.
Although the system was originally developed on ancient DEC
computers, and matured on VMS, it also runs well on UNIX systems.
Still, this is very "old fasioned" software: PPPL legacy code.
Applications programs use UREAD with the simple call
CALL UREAD('<prompt>$')
Where <prompt> is to be sent to the terminal if a user at a terminal
is in control of the applications program. The response is decoded
with:
I=IDCOD(IER) ! decode integer input, or
F=FDCOD(IER) ! floating point input, or
FR8=R8DCOD(IER) ! real*8 floating point, or
CALL CDCOD(STR) ! return character data CHARACTER*(*) STR
! all alphabetic characters UPPERCASE
CALL CDCODL(STR) ! return character data (STR); no change
! to case of alphabetic characters
(additional calls are available-- see description of FORTRAN
interface). Similar results can easily be achieved with FORTRAN
formatted READ or ACCEPT statements. However, UREAD supports
additionally functionality:
> typeahead support. User may anticipate and answer several
prompts on a single line.
> control transfer. If a script file exists with appropriate
prerecorded answers to program prompts, it may be invoked
instead of the terminal user having to retype the answers
in each session. These control scripts or "indirect input
files" may invoke subfiles, allowing the creation of a
"modular" control system for your interactive program.
As an application code is developed it is usually used in fully
interactive mode-- the code developer/user tests the program, choos-
ing every option explicitly. This makes the code relatively easy to
debug-- the developer can choose the order of testing and knows what
specific option or subroutine is executing if the program fails.
As the program matures, however, certain control paths are likely
to emerge as the most commonly used. If the program uses UREAD these
control paths may be recorded in indirect input files which may be
invoked to navigate the paths automatically without further user
intervention. If there is a point in the path where the user must
make a choice this may be parametrized in the indirect input file
such that the user must specify a parameter choice.
The effect of this control option is to permit easy developement of
applications programs under an assumption of maximum flexibility of
use, without sacrifice of automation (via UREAD indirect input files)
as the program matures with patterns of common actual usage.
The availability of UREAD automated control options relieves the
code developer of having to develope special "easier to use" versions
of programs whose functionality is already fully covered in more
general (but intrinsically harder to use) applications codes. This
benefits users and code developers alike.
The ability of UREAD indirect input control files to invoke eachother
like subroutines permits design of a modular control system to go with
your interactive program. Use of modularized indirect input files
may also benefit other programs-- for example, if you use GRF3 to make
plots of 2d grid numeric data of the form f(x,y), you might create
an indirect input file "3DISOM.IFI" to generate a 3d isometric proj-
ection of the data. That file (if it kept control inside GRF3 and
subroutines) could be used to generate the same type of plot from inside
ANY program which calls GRF3. (GRF3 is described in the appendix of
the UFILES manual and is executed when you use UGRAF2 or other UFILES
2d data utilities).
If you have interactive program systems that get large and complicated,
the modular control capability of UREAD indirect input files benefits
in terms of flexibility and maintainability in a manner similar to the
benefits of use of modularized DCL or FORTRAN or any other computer
language.
UREAD sends prompts and reads control information or data for a FORTRAN
program. However, it also performs an interpretation of the input line.
If the input syntax indicates a UREAD command rather than data for the
main program, the UREAD command is executed. Only data which cannot be
interpreted as a UREAD command is returned to the calling program.
UREAD reads 512 character lines from the input file (or terminal).
However, interpretation is organized around the concept of a typeahead
buffer. This means the input is expected to consist of "words" which
are interpreted one by one, moving from left to right in the input
line. In UREAD, "words" are blank or comma delimitted strings, or any-
thing enclosed in double quotes. When a "word" cannot be interpreted as
a UREAD command it is returned to the main program for consideration.
As words are successfully interpreted, they are "pulled out" of the left
side of the input buffer, which is left justified to contain fewer and
fewer words. A new line is not read from the input file until the input
typeahead buffer is empty (all words interpreted).
If UREAD is reading input from a UREAD indirect input file, it expects
to find records containing prompts matching the prompt sent by the
calling program. UREAD will not return data from the file to the
calling program unless a matching prompt record is found. This prompt
match checking feature helps assure the integrity of file input.
The prompt match checking feature of UREAD may be disabled or redefined
by user command; more information on prompt match checking under
"commands" and "files".
When a UREAD application program calls UREAD and the typeahead buffer
is empty:
o The prompt passed in the UREAD CALL is sent to the terminal
if a user at a terminal is in control.
o An input line is read from the terminal or input file. If read
from the terminal an output file may be open, in which case BOTH the
prompt AND the input line are echoed to the output file. The output
file may later be used as an indirect input file. If read from an
indirect input file, the correct prompt must be found before data will
be returned to the calling program (prompt match checking).
o the input line is scanned for inline parameter substitution. UREAD
parameters are used in a manner similar to symbols in VAX DCL.
Parameterization of critical quantities (e.g. shot no. or smoothing
control parameter) enhances the flexibility of UREAD input files.
The following functions are performed on ALL UREAD calls:
o the first character of the typeahead buffer is checked. If it is
a UREAD special characacter, UREAD performs further processing (e.g.
parameter definition or control transfer). Typeahead beyond most UREAD
special functions is supported.
o If the first character is not a UREAD special character, UREAD
returns control to the caller for application-dependent decoding of
the input.
ENTER UREAD SUBROUTINE
\/
|------YES----Q1: TYPEAHEAD BUFFER EMPTY?--NO---.
V |
Q2: READ BUFFER FROM TERMINAL? |
IF YES: ECHO TO OUTPUT FILE IF ONE IS OPEN |
READ BUFFER FROM INPUT FILE? |
IF YES: DO PROMPT MATCH CHECKING |
IF END OF FILE: CLOSE, GO TO Q1: |
SUBSTITUTE ANY UREAD PARAMETERS IN BUFFER |
V Y
CHECK TYPEAHEAD BUFFER CONTENTS <---------------'
UREAD COMMAND?--NO--------------------------------------.
OPEN INPUT FILE, NEW TYPEAHEAD BUFFER, GO TO Q2, OR |
OPEN OUTPUT FILE, NEW BUFFER, GO TO Q2, OR |
CLOSE OUTPUT FILE, RESTORE OLD BUFFER, GO TO Q1, OR |
UREAD PARAMETER DEFINITION. EXECUTE DEFINITION |
PULL DEFINITION OUT OF BUFFER, GO TO Q1, OR, |
COMMENT: FLUSH BUFFER, GO TO Q2, OR |
CONDITIONAL BRANCH: EXECUTE, GO TO Q1 WITH |
BUFFER POSSIBLY MODIFIED |
Y
HAVE INPUT FOR CALLING PROGRAM. <-----------------------'
IF INPUT FROM FILE AND NO PROMPT MATCH, GENERATE ERROR
MESSAGE AND READ FILE LOOKING FOR MATCHING PROMPT
OTHERWISE RETURN CONTROL TO CALLER.
(This section written originally for VMS systems; UNIX-relevant
commentary has been added).
To make best use of a UREAD program it should be defined as a "foreign
command". If your program has the name URDISK:[URDIR]URPROG, define the
DCL symbol
$ URPROG :== $URDISK:[URDIR]URPROG
Then to execute the program, just type "URPROG"; note the "RUN" command
is not necessary. In the DCL symbol definition the disk and directory
of the program must be explicity defined.
(Equivalently, in UNIX, put the UREAD program binary into a directory
which is on your PATH, so that the program acts as a command and will
accept typeahead input as arguments).
UREAD programs which are defined as foreign commands permit typeahead
directly from the DCL command level into the UREAD typeahead buffer.
thus the DCL lines
$ OPCODE := PLOT
$ URPROG /SHOT=12345/OPTION='OPCODE'/ @URFILE
does the following: (1) substitutes the value of the DCL parameter
'OPCODE' into the command line; (2) activates URPROG; (3) loads the
UREAD typeahead buffer with everything in the command line after
"URPROG". Then UREAD will define the UREAD parameters SHOT and OPTION
and transfer control of the URPROG program to the indirect input file
URFILE (normally, URFILE.IND).
A similar UNIX shell script might look like this:
#
set ishot = $argv[1]
set opcode = $argv[2]
urprog /shot=$ishot/opcode=$opcode/ @urfile
In UNIX the script file is normally named "urfile.ind" using lowercase
letters.
VMS terminology: logical name
UNIX terminology: environment variable
If a filename is assigned to the logical name UREAD_INI, then when
UREAD is initialized in a UREAD program, that file will be read and
UREAD commands therein (e.g. definition of a default set of UREAD
parameters) will be executed. Note: the UREAD_INI file may only
contain UREAD commands (e.g. "*" commands or "/" parameter definitions)
which do not result in an attempt to send data to the controlling
program. Thus a UREAD "@" command (invoke indirect input file) or
an attempt to supply data to satisfy the program's first prompt may
not be included in the UREAD_INI file; an error will be reported.
The main intent of this file is to provide a mechanism for defining
a default set of UREAD parameters. For example, in [TRANSP] I
assign a file containing the following lines to UREAD_INI:
/YM==D RX4: E TFTR.YM
/YS==D RX4: E TFTR.YS
/TFTR==D HX3: E TRANSP.TFTR.DATA
providing UREAD parameters which make it easy to tell UFILES utilities
look for data in RX4:[TFTR.YM],RX4:[TFTR.YS], or HX3:[TRANSP.TFTR.DATA].
(These are VMS directory paths).
The parameters contain control "phrases" understood by UFNTER, the file
name specification routine which is called by all UFILES interactive
utility programs. More info on UREAD parameters is available below.
In UNIX, standard UREAD parameter definitions would be placed in a
file pointed to by the UREAD_INI environment variable.
The default mode of input to UREAD is through a typeahead buffer. The
reason for this is that most program input comes not in "sentances" but
individual "words", e.g. a number or a menu option select code. If you
are familiar with a program and know what it is going to ask you next
(after the current prompt), then, it may be convenient to load up the
typeahead buffer with as many answers as you know. This will result in
each "word"/answer being processed in its turn. The prompts (and
attached menus, explanations, etc.) to which these word/answers
are addressed are not displayed (unless the UREAD debug echo switch
*E is on) so the program runs more quickly. If an error occurs
processing typeahead buffer input, the buffer is flushed and control
is returned to the user immediately.
If a program requires "sentance" or multi-word input in response to
a single prompt, typeahead is disabled.
UREAD input words may always be seperated with either a blank or a
comma (","). Multiple consecutive blanks are not significant.
Consecutive commas with no non-blanks inbetween are interpreted as
"null" words which the application program may interpret to mean
e.g. retain a default value.
Thus: "A 1 2", "A 1 2", "A,1,2", "A, 1, 2 ", "A , 1 , 2"
will all be interpreted the same way, but "A,,1,,2" may lead to a
different result.
If a program accepts single characters or fixed length words in response
to a given prompt, it will be possible to typeahead through such prompts
while omitting the blank or comma delimiter. However, variable length
items (e.g. integers, floating point numbers, filenames, ...)
must always be blank or comma delimitted.
*new Feb 1988* ANY STRING enclosed in DOUBLE QUOTES (") will be sent
back to the applications program as a single word. This word may
contain leading and/or imbedded blanks and/or other special UREAD
characters; also, alphabetic characters are not converted to upper
case. WARNING: many existing applications programs rely on UREAD
to remove leading blanks, do upper case conversion, etc., so careless
use of this syntax may break many applications programs. The
applications program sees the string as written, not including the
double quote delimitter characters. To imbed a double quote character
in such a string type it twice.
Typeahead beyond quote string words is supported.
Examples:
User inputs: Applications sees (as one word):
============ ================================
"" (null word: represented as blank)
"this IS a TEST" this IS a TEST
"""this is a test""" "this is a test"
"""" "
"@" @
" **invalid** mismatched delimitters
""" **invalid** mismatched delimitters
"""hello"" **invalid** mismatched delimitters
A program using UREAD calls will allow the user to interchange these
two sessions with the same result (program prompts capitalized):
session 1:
ENTER DAY: 24
ENTER MONTH: jun
ENTER YEAR: 1985
session 2:
ENTER DAY: 24 jun 1985
The application program is coded to generate session 1 but thru UREAD
session 2 is also automatically available.
UREAD commands are initiated when the asterisk ("*") is encountered
as the first character in the typeahead buffer. The following
commands are available ( <> enclose arguments; [] indicates optional
argument):
*A [<msg>] - stop (ABORT) the program with message (if terminal is
attached, user is prompted for verification).
*C [<dcl command>] - spawn subprocess. If no command is specified,
an interactive subprocess is spawned (not avail. in batch).
"better than ctrl(C)." (in UNIX arguments to *C do not work).
*D invoke DEFAULT mode - prompt only when typeahead buffer is empty
*E invoke ECHO mode - echo all prompts and replies. *** used to
debug indirect input files; generates extra diagnostics;
opposite of *D.
*F display FILES which UREAD has open for input or output; display
UREAD control settings.
*H or *J - access this HELP file (VMS only).
*N NOVICE mode. Flag for explanatory messages is on.
*P <filename>. Specified file <filename> receives subsequent
SGLIB plot output. Implimented via SGLIB RINITT call; all
standard SGLIB switches supported-- see SGLIB HELP.
*X EXPERT mode. opposite of *N.
*T <msg> - send message (e.g. from indirect input file to tty or
batch job log file).
*S SUPPRESS prompt mismatch error message (retaining prompt
match checking function)
*S* SUPPRESS prompt match checking entirely (new Feb 1988)
*R RESTORE prompt mismatch error message (opposite of *S).
(If *<char> is not a command it is returned to main program)
*U <keyword_list> execute keyword functions. Valid keywords:
VIDEO or REVERSE-- reverse video prompts for certain terminals
BOLD-- for boldface prompts
UNDERLINE-- for underlined prompts
NO -- ordinary text prompts (no special attributes).
UREAD "string parameters" can be defined -- these are UREAD script
variables -- similar to DCL symbols in VMS DCL, or UNIX shell script
variables.
/NSHOT=12345
the special character slash ("/") indicates that the definition of
a parameter is at hand; the item to the left of the equal sign after
the slash is the parameter name. It may consist only of alphanumeric
characters (case insensitive) and "_" or "$"; imbedded blanks are
not allowed. The item to the right of the equal sign is the value
to be associated with the name. All characters except "/" are legal
in the parameter value field (unless the "/" is enclosed in double
quotes), to a maximum of 48 characters. A "/" terminates the value
field. The value field must contain some nonblank characters.
The name field is always converted to uppercase. When UREAD syntax
indicates the definition or use of a string parameter, the name is
always converted to uppercase.
There are two types of string parameters: "local" and "global".
"Local" parameters are known only to the current UREAD control input
file; "global" parameters known at all levels of input.
Local parameter values may be passed between UREAD input files--
for more information read about UREAD indirect input files.
local parameter definitions have the form
/<name>=<value>
space for 20 parameter definitions are reserved for each input file.
global parameter definitions have the form
/<name>==<value>
the double equals sign indicates a global definition.
Space for 500 global parameter definitions is provided.
Typeahead beyond a parameter definition line is possible only if the
parameter definition is terminated with an extra "/", i.e.:
/<name>==<value>/ addl. typeahead stuff...
There are three forms of parameter subsutitution-- i.e. input syntax
which tells UREAD to fetch the value of a predefined parameter,
substitute that value into the typeahead buffer, and treat it as if
it had been typed in directly:
{name}
results in the substitution of the named parameter's value.
'name'
/name
do likewise. However, there is precedence-- wiggly bracket
substitutions are done first, the single quote substitutions, then
"/" substitutions.
"{ ... }" substitutions support "recursion": the innermost pairs are
substituted first, then intermediate pairs, then outer pairs.
Parameter substitution inside double quote strings is generally
suppressed. However, it may still be invoked by using *two
consecutive single quotes* to specify the substitute operation.
I.e.:
"PARAM is ''PARAM''"
Will cause the value of PARAM to be substituted inside the pair of
double single quotes.
This parallels the rules used in VAX DCL.
definitions:
/IC=3
/IND3=5
/S5=12345
substitution examples; input lines...
/IND3 ... is replaced by "5" and returned to caller
/IND'IC' ... has the same result
/S5 ... is replaced by "12345" and returned to caller
/S'IND3' ... has the same result
/S'IND{IC}' ... has the same result
'S{IND{IC}}' ... has the same result
{S{IND{IC}}} ... has the same result
/S5 'IND3' {S5} /IND3 ... leads to input line "12345 5 12345 5"
typeahead and parameter substitution are compatible.
Primitive arithmetic may be performed on parameters which are
decodable as integers. The syntax is
/<name>=.+<number>
which causes the amount <number> to be added to the value of the
parameter with name <name>. Note the dot "." is necessary to dis-
tinguish an arithmetic operation from merely assigning the value
"+<number>" to the named parameter.
Available operations are:
addition "+" subtraction "-"
multiplication "*" division "|"
Examples (with typeahead syntax, "/" terminates a definition):
/IC=1/IC=.+1/ ; set IC=1 and add 1; result IC=2
/K='N'/K=.-'M'/ ; set K=N-M where N and M are predefined integer
; parameters
This limited arithmetic ability allows parameters to be used
(a) to set up control loops in UREAD indirect input files-- a
parameter is used as a loop counter
(b) have 'indexed' parameters; i.e.
/S1=12345/S2=12346/S3=12347/IC=3/
*T THIS IS SHOT 'S{IC}'
The UREAD *T command sends "THIS IS SHOT 12347" to the terminal.
UREAD permits the creation and/or invokation of "indirect input files"
which contain program prompts and their answers. The indirect input
files may also contain extra comments, UREAD parameter definition or
use, parameter arithmetic, conditional or unconditional branching or
looping, and UREAD "*" commands-- the complete UREAD syntax. UREAD
indirect files may invoke subfiles: a stack is maintained with up
to nine files open simultaneously. Each file has its own typeahead
buffer and set of local parameters (its "context"). Parameters may
be passed to subfiles. Global parameters may be set or modified by
any subfile.
UREAD indirect files permit the creation of modularized documented
automated control systems for your interactive programs. In effect
UREAD gives the user interaction of any program the features of a
computer language and allows any degree of automation of the
interactive program up to and including total automation in batch.
To create a UREAD indirect file for a FORTRAN program, you run the
program and create a UREAD output file. This file will record the
program prompts and your instructions as you type them in. The
resulting file is an ordinary text file which can be editted to
remove mistakes, insert extra comments, or to add parametrization,
branching, etc.
UREAD output files are opened when an input line of the form
"><filename>"
is encountered. The special character ">" indicates "open a UREAD
output file". <filename> does not include an .ext extension, a
default extension is supplied.
Typeahead in the form
<input ... input> ><filename> <input ... input>
is permitted. However, the typeahead input after the file open
is deferred and is not executed until after the output file is
closed: this typeahead input is associated with the file stack
level from which the file was opened; a new, empty typeahead
buffer created as <filename> is opened.
To close an output file, just type ">" (carriage return). No
typeahead beyond a file close is possible (the typeahead buffer
associated with the file being closed is terminated and the buffer
from the previous file is reopened).
More than one output file may be open simultaneously. If the files
are later executed as indirect input files, the n+1th output file
is invoked as a subfile of the nth output file.
In this terminal session (program prompts capitalized):
PROG: ENTER SHOT NO.: >getdata
PROG: ENTER SHOT NO.: 'nshot'
PROG: ENTER CHANNEL NO. >plotdata
PROG: ENTER CHANNEL NO. 3 plot exit
PROG: ENTER CHANNEL NO. 7 plot exit >
PROG: ENTER CHANNEL NO. shot
PROG: ENTER SHOT NO.: >
Two indirect files are created: GETDATA and PLOTDATA (filename
extensions are supplied). GETDATA has a variable UREAD parameter
NSHOT, the shot number. PLOTDATA is a subprocedure of GETDATA and
requests plots of "channels" 3 and 7 without rescale options. The
">" at the end of the input line "7 plot exit >" closes PLOTDATA.
In a later session at the prompt "PROG: ENTER SHOT NO.:" a user
may enter "@GETDATA/NSHOT=12345" to run GETDATA on shot 12345.
This will also run PLOTDATA as a subsidiary indirect input file.
The file GETDATA looks like: ! The file PLOTDATA looks like:
;PROG: ENTER SHOT NO.$ ! ;PROG: ENTER CHANNEL NO.$
'NSHOT' ! 3 PLOT EXIT
;PROG: ENTER CHANNEL NO.$ ! ;PROG: ENTER CHANNEL NO.$
>PLOTDATA ! 7 PLOT EXIT >
;PROG: ENTER CHANNEL NO.$
>
Technicality-- when ">PLOTDATA" is encountered as GETDATA is being
READ as an indirect INPUT file, it is interpreted as "@PLOTDATA":
an indirect file read command, not a file write command.
A UREAD indirect input file is invoked with a line of the form
@<filename>
If in <filename> the filename extension .ext is omitted, a default
.ext is supplied. The text lines in the file <filename> will control
the program being run, without the user having to type anything more,
provided the file satisfies a prompt match condition (more information
available). Indirect input files may be invoked in conjuction with
typeahead:
<input ... input> @<filename> <input ... input>
However, the input after the "@<filename>" is deferred and will not
be executed until after the instructions in file <filename> are
completed. A new, empty typeahead buffer is allocated to the newly
opened file.
UREAD output files include records containing the program prompts
sent down by the applications program to request input or control
information. When UREAD files are read back on input, these prompt
records are checked against the prompts being sent from the program.
If a character-by-character comparison of the Nth thru Mth (blank-
delimitted) words of the program prompt and the recorded prompt
reveals a disagreement, further input from the indirect input file
is suspended and a "prompt mismatch" error message is issued-- with
traceback to the file record where the condition was detected. Input
is suspended until a matching prompt is found; if none is found in the
current input file it is closed and the next higher level file in the
input stack is tried-- and so forth back eventually to SYS$INPUT.
The comparison word counts N,M are application dependent, but the
default value used in most applications is N=1, M=3.
Prompt match checking is useful because it prevents the sequence
of input from the indirect input file from running a program "out
of control". The inclusion of program prompts in the input files
also provides a means of automatic documentation.
However, the user or input file may suppress prompt match checking
by entering the UREAD command "*S*". See "commands". See also
information on the use of the $MATCH reserved global parameter.
When designing indirect input files to automate interactive codes
the programmer/user should expect common error conditions (e.g.
data file not found), so that if a prompt mismatch occurs a
matching prompt will be provided further down in the input file to
resume program control.
The UREAD system supplies a reserved global UREAD parameter named
$MATCH which indicates whether a prompt has been matched or not.
$MATCH has one of two values: "TRUE" or "FALSE". This allows
an indirect input file to be "programmed" to anticipate a likely
prompt mismatch state, before UREAD detects it. In the following
hypothetical example:
;PROG: ENTER NAME OF FUNCTION TO PLOT:$
'FCN_NAME' ; USER SUPPLIED FUNCTION NAME -->PROG
;
;PROG: SPECIFY TYPE OF PLOT:$
; -- check if we have a prompt match --
;
?$MATCH="FALSE" SKIPTO BADEXIT
;
'PLOT_TYPE' ; USER SUPPLIED PLOT DISPLAY TYPE -->PROG
;
?SKIPTO GOODEXIT
; -- error --
:BADEXIT
*T ?? the name FCN_NAME = 'FCN_NAME' is not known ??
:GOODEXIT
PROG (is assumed) to prompt for PLOT TYPE only if a valid
FUNCTION NAME is specified. The ?$MATCH... UREAD statement checks
the prompt match status; a mismatch is assumed to denote a bad
FUNCTION NAME as passed through UREAD parameter FCN_NAME.
UREAD keeps track of its open input and output files in a stack. The
stack information associated with each file includes:
filename record count typeahead buffer local parameter definitions
file type: input or output
which constitute the open file's "context". The stack has appearance
S0: SYS$INPUT ... this is the "base" element; it is never removed
S1: output file #1 (opened from SYS$INPUT ">" directive)
S2: output file #2 (opened from SYS$INPUT when S1 already open)
... ...
SN: output file #n (opened from SYS$INPUT when SN-1 already open)
SN+1: input file #1 (opened from SYS$INPUT "@" directive)
SN+2: input file #2 (invoked with "@" as subfile from SN+1)
... ...
SN+M input file #m (invoked with "@" from SN+M-1)
limit: n+m .le. 9
input files are "popped" off the stack (and closed) when end-of-file
is encountered; output files are "popped" and closed when an input line
of form "> " is encountered from SYS$INPUT.
If output files are open, only the highest numbered file receives echoes
of program prompts and SYS$INPUT input lines. If input files are opened
the highest numbered input file is in control; input file input is never
echoed to an output file. When an output file is later used as an input
file, then, the sequence of stack states occurring originally will be
recreated excepting only that the file is flagged as input rather than
output.
UREAD local parameters are attached to a file "stack element"--
i.e. whenever a new file is opened, whether for output or input,
local parameters that were accessible from the previous file level
are generally no longer accessible. (A globally defined parameter,
on the other hand, is always accessible and remains defined until
explicity deleted). However, local parameters may be passed from
file to file:
@<filename>/name1/name2/name3=value3/ <typeahead stuff>
results in parameters "name1", "name2", "name3" being inserted in the
local parameter table for the file <filename> (if successfully opened).
The values of "name1" and "name2" are copied from the previous file
(stack element) local parameter table, or the global parameter table.
"Name3" is defined "in-line" and receives the value "value3". "Value3"
may include an arithmetic operation. (For more info, see the help
section on parameters).
The final slash "/" preceding <typeahead stuff> terminates "value3" and
the parameter passing fields; <typeahead stuff> is retained in the
typeahead buffer attached to the file from which <filename> is being
opened. (For more info see modules on input or output files.)
The same syntax may be used when creating an output file with ">".
The semicolon (";") is the UREAD comment character (NB DMC Feb 1988:
this is application dependent; some applications use "!" for the
comment character, but for the remainder of this discussion it will
be assumed that the semicolon is being used). If the first
character in the typeahead buffer is a semicolon, the remainder of
the line is deemed a comment and will not be returned to the calling
program, and the next line from the tty or input file will be read
for control input. In indirect input files the semicolon is also
used as the leading character in a prompt echo. This line in the
indirect input file is not strictly a comment, however, since a
match with a program prompt is required to use the non-comment
control information in the file (see "prompt_match_checking").
example (program prompt CAPITALIZED, user response lower case):
PROG>ENTER SHOT NUMBER:12345 ;this is a good shot
PROG>ENTER SMOOTHING FACTOR:1.5e30 ;but the data is a bit noisy
The program will decode 12345 and 1.5e30 as shot number and smoothing
factor, respectively-- but will not be effected by the information
following the semicolons. However, if a UREAD output file was open,
the comments were recorded there.
Conditional or unconditional branching (transfer of control between
records) is supported in UREAD indirect input files. A branch
request is initiated when a question mark ("?") is encountered as
the first character in the typeahead buffer. The format for an
unconditional transfer is
?SKIPTO <marker>
where <marker> is the name of a target label (see definition).
A conditional transfer has form:
?<parameter>="<value>" SKIPTO <marker>
or
?<parameter>#"<value>" SKIPTO <marker>
where <parameter> is the name of a UREAD parameter (see definition),
"=" or "#" are logical operators (equals or not equals, respectively),
and "<value>" is the test value with which the value of <parameter> is
compared to determine whether or not to execute the SKIPTO branch.
SKIPTO branches can be upward or downward in the (sequentially read)
UREAD indirect input file. An upward branch (to an earlier record)
allows the creation of loops (the designer of such a loop should take
care that the exit condition of the loop is well defined).
A second type of branch involves no control record transfer:
?<parameter>="<value>" <anything>
results in <anything> being processes as input only if the test
is satisfied; otherwise the typeahead buffer is flushed and the
next input line is read.
The following sequence of records might appear in an indirect input
file:
;PROG>AVERAGE THE DATA (Y/N):$ ; this is the program prompt
?AVER_FLAG="F" N ; AVER_FLAG should have value T or F
?AVER_FLAG="F" SKIPTO EXIT
?AVER_FLAG="T" Y
; send error message to terminal; echo bad value
?AVER_FLAG#"T" *T (NOT T OR F) INVALID VALUE OF AVER_FLAG: 'AVER_FLAG'
...
<intervening control records>
...
:EXIT ;this is the target marker for program exit
;PROG>DO ANOTHER SHOT? (Y/N):$
N
AVER_FLAG here is a UREAD parameter (see defn); *T is a UREAD
command to transfer a message to the tty/ batch log file; the
construct 'AVER_FLAG' causes the value of the parameter to be
substituted into the error message (which would be displayed only
if AVER_FLAG did not have one of its legal values, T or F).
When a SKIPTO <marker> is encountered, UREAD reads sequentially through
the input file looking for a line which starts with
:<marker>
as may be seen in the example.
If the marker is not found the file is rewound once and the top half
of the file is searched. This allows branching to an earlier record in
the control file (i.e. looping). If still not found, an error is
reported.
Note that the marker must be found at the START of the line (i.e.
leftmost nonblank characters-- as UREAD does not perform typeahead
scanning when in marker search mode. However, UREAD or program control
items may be present inline after the :<marker> (i.e. typeahead past
a marker is legal).
Looping consists of using a combination of parameter arithmetic
and branching to execute a control loop.
A simple example follows (set symbols "{}" have precedence; set symbols
"{}" and single quote "'" are inline substitution characters):
/IC=0 ;initialize loop counter
:LOOP
/IC=.+1 ;increment loop counter
?S{IC}="0" SKIPTO EXIT ;if the IC'th S item is 0, exit...
?S{IC}="X" SKIPTO LOOP ;if the IC'th S item is X, try next item
;ENTER NEXT S ITEM:$ ;anticipated program prompt...
/S'IC' ; slash ("/"), single quote ("'") and symbol substitution
; pair ("{","}") for multiply indirect symbol references
; if IC="1", 'S{IC}' results in substitution for the value S1
;ENTER S PROCESS CODE:$
@GOODPROC ; if we got this far keep doing the right thing...
?SKIPTO LOOP ; and go on to do the next one right, too...
:EXIT
(PPPL only)
(Be familiar with UREAD indirect input files before reading this...)
The file USR:[UFILES]GENLOOP.IFI contains code for a generic UREAD
loop controller. It contains no program-specific prompts and may
be used by any program using UREAD.
It expects input UREAD parameters
/S1==<first shot no.>/S2==<second shot no.>/ ...
/S<n>==<last shot no.>/S<n+1>==0/ ; a shot list
And a subprocedure name, e.g.
/SUBIFI=MYCTRL.IFI ; name of UREAD input file to execute inside loop
The subprocedure file should accept the parameter 'NSHOT' to be the
current shot number (GENLOOP defines this from S1, S2, ...) and it
should leave program control at the SAME prompt where it starts.
The program [TRANSP.TFTR.STARSHOT]STARSHOT.EXE will generate a UREAD
indirect input file containing the S1, ... definitions; in DCL:
$ MAKELIST :== $TREXE:STARSHOT
$ MAKELIST TESTLIST
runs an interactive program allowing you to create TESTLIST.IFI which
can then be invoked in any UREAD program to define S1, S2, ...
On VAX and UNIX systems at PPPL the UREAD system is actually used
in many applications. Here are some examples:
The TRANSP code produces a random access
binary plot file which may be accessed with an interactive program
RPLOT. Hundreds of input data and/or analyzed output data functions
may be plotted. In the TRANSP batch job, however, a fixed sequenced of
plot displays are desired (i.e. plasma parameters, then power balances,
then confinement times...). This is achieved using UREAD control files.
there are two levels of input files. A subfile creates multiple profile
plots at specified times (specified as UREAD parameters) and time traces
at specifed profile positions (also UREAD parameters). A master file
decides which data are to be plotted in this way and in what order-- and
makes parametrized decisions (e.g. do not plot beam data if there was no
beam).
The generalized UFILES smoothing utilities offer the flexibility of many
options, but the volume of data requiring smoothing prior to input to
TRANSP is such that interactive decision making at each option node for
every input data file can be very time consuming. Therefore a
batch job with UREAD control files has evolved for each standard type
of data. The options and parametrization of the control file is
specialized to the data type. UREAD branching/looping is often used
to process several shots in a single job. Plotting output is produced
which is scanned to verify the results of the smoothing.
Preparation of input data is the most time consuming aspect of operating
a time dependent data analysis code like TRANSP. The UREAD automation
facility provides a major productivity gain in this area.
UREAD control files are used for data translation and averaging as well
as smoothing.
(obscolescent information -- TFTR is long gone!)
NB dmc Feb 1988-- the DCL has moved to TRANSP$:[TRNSL] and has changed
some. This information is specific to PPPL: VMScluster for TFTR
data analysis.
To see an actual example of use of "advanced" UREAD features, see
RX4:[TFTR.YS]YSBATCH.COM. This is an interactive DCL interface which
allows a user to set up a translation of radiometer ECE raw data into
a temperature profile evolution 2d UFILE for a series of TFTR shots.
The procedure uses the interactive UREAD program MAKELIST to accept the
list of shot numbers and DCL INQUIRE for some additional parameter
choices (e.g. calibration file number). Then a batch job (YSTRAN.COM)
is submitted which uses the UREAD_INI logical assignment to set up
as UREAD parameters the shot list and auxilliary parameters such as
calibration file number. The UREAD FORTRAN program YSTRAN is executed.
The generic loop UREAD file RX4:[TFTR]GENLOOP.IND controls the loop
over shots, while the subsidiary UREAD file YSTRAN.IND controls the
data conversion for each shot. Plots are created for each successfully
translated shot.
The same FORTRAN program YSTRAN program can also be run in the simple
fully interactive mode with explicit user control over each option
for each shot. For more information on this and other similar
applications see the help file, access via symbol "TRHELP" in the
[TFTR] area on RAX or HAX.
UREAD language elements:
/name=value local parameter definition (20/ input file level)
/name==value global parameter definition (200 parameters max)
/name parameter invokation
'name' or {name} "inline" parameter invokation; {,} have precedence
>filename create UREAD indirect file (only from terminal)
@filename use UREAD file to control program
technicality-- if ">" is encountered in an indirect input
file it is treated as an "@".
; anything after a semicolon is a comment
?name="value" SKIPTO marker Parameter test/ branch
?SKIPTO marker Unconditional branch
?name#"value" anything Conditionally execute "anything"
"=", "#" are "equals", "not equals" logical operators
:marker branch target marker (label)
*command UREAD command
e.g. *E - echo/debug input file
*C - spawn subprocess
Anything not listed is returned to the UREAD caller for interpretation.
The UREAD library includes dozens of routines which might be of use in
a particular application. The description of routines is divided up as
follows:
INITIALIZATION - a call to initialize UREAD COMMON blocks is required.
UREAD SUBROUTINE - sending prompts, retrieving data with CALL UREAD.
DATA DECODING - how to fetch or decode the data read in by UREAD.
COMBINED CALLS - calls which combine the above two steps.
TIC interface - UREAD emulation of the TIC FORTRAN interface.
TERMINAL CONTROL - various UREAD facilities.
ERROR HANDLING - routines for reporting errors; clearing the typeahead
input buffer after an error.
MODIFICATIONS - certain UREAD characteristics (e.g. typeahead support)
can be switched on and off.
PARAMETER ACCESS - UREAD string parameters (which are to UREAD input
files what DCL symbols are to DCL .COM files) may be defined or
read accessed from FORTRAN programs.
Miscellaneous other capabilities and options are described.
The programmer using UREAD CALLs should be familiar with the UREAD
user interface as well as the FORTRAN interface described here.
(dmc 23 Mar 1993)
For portability reasons, codes which use UREAD logical functions
LXOUT, LCHAR, LYES, or LYESC, must DECLARE these logical functions.
An option for doing this is to use the ULOGICAL include file:
C declare logical functions:
INCLUDE 'ULOGICAL'
On DEC machines, the code will function correctly if the declaration
of the function name as LOGICAL is omitted. Unfortunately, on other
machines the omission of the LOGICAL declaration leads to malfunction
at runtime.
UREAD COMMON blocks MUST be initialized for proper execution.
To do this,
CALL UINITA(ILUN)
before the first CALL UREAD. This call also initializes the SG library
COMMON blocks with a CALL INITT. There is a terminal-dependent page
clear to put the terminal in character mode with a blank screen. The
argument ILUN tells UREAD to allocate the logical units (i/o channels)
ILUN thru ILUN+8 for the UREAD file stack: Your program SHOULD NOT USE
these logical unit numbers for anything else. If ILUN is zero or out-
side the range 11 to 90, logical units 10 through 18 are allocated.
Alternatives:
If you use the URTIC UREAD/TIC emulator, CALL AT_INIT0 generates a
CALL UINITA(0).
If you do not want the INITT call to occur (or you call it elsewhere),
then:
CALL ULUN00(ILUN) ! to control UREAD file stack LUNs
CALL USINIT ! to initialize UREAD COMMON
If you CALL INITT yourself your terminal will be left in Tektronix
mode. AFTER initialization, the UREAD call CALL NEUPAG will clear
the screen and leave the terminal in text mode (cf terminal control).
Right after the main UREAD initialization call (UINITA or USINIT) the
following calls might be desired to modify UREAD characteristics.
These calls can be hazardous and should not be attempted without
good reason...!
CALL URDEXT('CTL')
changes the default UREAD control file filename extension to .CTL; the
default is .IND (for "indirect").
CALL URDCRI(1) ! enable acceptance of null input line
CALL URDCRI(0) ! disable acceptance of null input line
disabled (i.e. UREAD reprompts) by default. A null line is generated
when the user types (CR) immediately at the program prompt.
CALL URDCMC('!') ! changes the UREAD COMMENT CHARACTER to "!".
the default is ";". IF THIS IS CHANGED for a given application, old
control files will be rendered unusable.
CALL USPUNC(',;') ! set up the characters "," and ";" as
"punctuation". These characters will both delimit words and be
visible to the application as "words". E.g. if the user enters
the string "ALPHA,BETA ; C", the application will see the sequence of
words "ALPHA", ",", "BETA", ";", and "C" (5 items total). Without
the call to USPUNC, UREAD treats commas as well as blanks as word
delimiters which may be hidden from the application code.
CALL UPRSET(char) ! changes the appearance of UREAD prompts
on VT100 screens, depending on CHAR: 'R' for reverse video,
'B' for bold, 'U' for underline. Any other string yields prompts
in ordinary text mode.
CALL URDPMA(i,j) ! prompt match checking is done on words i
thru j of the program prompt; j.ge.i, i.gt.0 required for effective
prompt match checking. Default: CALL URDPMA(1,3). For a description
of prompt match checking, see info on user_interface re. files.
CALL URDCMI(' .. uread command string .. ')
Any UREAD user command may be executed. See description of the user
interface. Example: CALL URDCMI('*S*') will suspend file prompt
match checking, but the user may re-enable this if he/she knows to
type "*R" at a program prompt.
When an applications program, having initialized UREAD COMMON, needs
data to be input from the terminal or UREAD input file, it may request
such data by issuing a call of the form:
CALL UREAD('prompt$')
This tells the UREAD system to get the data. UREAD checks the typeahead
buffer first, then reads from the terminal or file if necessary. UREAD
traps UREAD instructions, so control is returned to the caller only when
a data item to be interpreted by the caller is at the top of the type-
ahead buffer. (More info below on decoding this input).
The prompt string may contain any sequence of characters except imbedded
dollar signs "$". This terminator character is an old FORTRAN - IV com-
patibility feature-- it used to mark the end of a string; it is not
required in new code, i.e.
CALL UREAD('prompt')
now works just fine.
The prompt appears on the terminal followed by a carriage return; the
user may type input on the next line. If It is desired that the prompt
and user response all be on the same line,
CALL UREAD('prompt$$')
with double dollar sign terminator does this.
NOTE -- suppression of carriage return after prompt *does not work*
on VMS systems.
Care should be taken in constructing the UREAD prompts, especially if
the program being written is fairly large and will become a candidate
for automation via UREAD indirect input files. Thru the prompt match
feature the prompt becomes a form of automatic documentation in the
indirect file. The prompt should give a fair indication of what data
is sought, even when preceded by explanatory messages. I also like to
imbed the calling subroutine name in the prompt.
A call of the form
CALL UREAD('$')
generates a null prompt. UREAD reads from the terminal without sending
a prompt. UREAD reads from an input file without doing prompt match
checking. If you do your own prompting and use this type of UREAD call
throughout your applications program, there will never be any prompt
match checking. Your program can be controlled by any text input file
(which may or may not be a good idea).
After the UREAD CALL has returned control to the main program, a follow-
up call is needed to decode the input. Here is a list of typical calls:
LOGICAL L
CHARACTER*n STR
C ... after UREAD call ...
I=IDCOD(IER) !decode as integer IER=0 if successful, note 1
F=FDCOD(IER) !decode as real number, IER=0 successful, note 1
FR8=R8DCOD(ier) !decode as REAL*8 number, IER=0=success, note 1
CALL CDCOD(STR) !extract length n CHARACTER string, note 2
CALL CDCODL(STR) !extract length n CHARACTER string, note 2
L=LYES(0) !.true. if input char is "Y", .false. o/w note 3
L=LYESC('char') !.true. if input char*1 is "char", .false. o/w 3
L=LCHAR('char') !same as LYESC except see note 4
notes:
a WORD is a sequence of characters terminated by blank or comma, or,
a literal imbedded in double quotes (" ... "). A CHARACTER is a
single character or a literal imbedded in double quotes. Unless
the item is a literal, UREAD left-justifies the buffer; CDCOD also
converts all letters to UPPER CASE.
1 one WORD is pulled out of typeahead. Error results in error
message and flushes typeahead buffer. Caller must declare
R8DCOD to be REAL*8.
2 one WORD is pulled out of typeahead and placed in STR. STR
is left-justified and padded w/ blanks. Truncation of the WORD
(if STR is too short) results in an error message.
==> if CDCOD is used, string is converted to UPPERCASE
==> if CDCODL is used, string is exactly as typed by user.
3 one CHARACTER is pulled out of the typeahead buffer. Match
tests are case-blind.
4 a CHARACTER is pulled out of typeahead only if it matches the
passed character. The match test is case-blind.
I=IXUOPC('charlist$') !return index in "charlist" of user input
!see note 4. ** return 0 if no match **
I=IXUOPW(wordlist,n) !return index to element in character
!array "wordlist" matched by user input
!** return 0 if no word matches input **
!see notes 4,5
L=LWORD('word') !logical function; return .true. if input
!matches "word", false othersise.
notes:
a WORD is a sequence of characters terminated by blank or comma, or,
a literal imbedded in double quotes (" ... "). A CHARACTER is a
single character or a literal imbedded in double quotes. Unless
the item is a literal, UREAD left-justifies the buffer and converts
all letters to UPPERCASE for comparison purposes.
...
4 a CHARACTER or word is pulled out of typeahead only if it matches
the passed character or word. Case-blind comparison used.
5 words passed to IXUOPW and LWORD should be left justified within
each array element. UREAD will do a case-blind character by
character comparison; trailing blanks or nulls have no effect
e.g.:
PARAMETER MAXOPT=3
CHARACTER*5 OPTIONS(MAXOPT)
DATA OPTIONS/'GET','PLOT','EXIT'/ ! TRAILING BLANKS OPTIONAL
...
CALL UREAD('PROG: ENTER OPTION>$$')
IOPN=IXUOPW(OPTIONS,MAXOPT)
UREAD reads input data in character format. The input line is left-
justified. Many, but not all of the data decoding routines convert
letters to uppercase.
When a CALL is made to a UREAD decoding routine (IXUOPC, LWORD, FDCOD,
etc.) and data is successfully decoded, it is "rotated out" of the
typeahead buffer, so that the next decoding call will examine the next
item in the buffer. Execution sequence of UREAD applications should
correspond to CALL UREAD / decode / CALL UREAD / decode with only one
item decoded between each UREAD call, so that UREAD may prompt and read
in case the typeahead buffer is empty.
As shown in the Usage_examples section, a combined decoding scheme may
be used in which the input line is first checked for known control
keywords; if none are recognized the typeahead buffer is left intact,
so that a numeric decode (FDCOD or IDCOD) may be tried.
Note that numeric decode calls always result in either a successful
decode (with the decoded number rotated out of the input buffer) or an
error message (with the typeahead buffer flushed). Therefore, if
control keyword input is to be accepted it must be decoded BEFORE the
numeric decode is attempted.
Here is some hypothetical code using UREAD...
(note: examples use UREAD logical function LXOUT which can be used
to suppress menu display/ explanatory message output if the UREAD
typeahead buffer is not empty, or a UREAD indirect input file (not a
user at a terminal) is in control of the program. More information in
the section on terminal control).
CHARACTER*8 ERRSTR ! error string
10 CALL UREAD('PROG: specify option:$$')
IF(LWORD('PLOT')) THEN ... plot data
ELSE IF(LWORD('LIST')) THEN ... list data types
ELSE IF(LCHAR('X')) THEN ... exit node
ELSE
CALL CDCOD(ERRSTR) ! did not recognize input ... ERROR MSG
CALL UERMSG('% UNKNOWN OPTION',ERRSTR,0)
ENDIF
GO TO 10
CHARACTER*2 OPLIST(5)
DATA OPLIST/'HE','WF','RW','PL','X'/
C if user at tty is in control, explain the options ...
IF(LXOUT(0)) TYPE 1001 ...
20 CALL UREAD('PROG: specify shot number or alternate option:$')
I=IXUOPW(OPLIST)
IF(I.NE.0) GO TO (100,200,300,400,500) I ! process options
C input not an option code-- must have been a shot number
ISHOT=IDCOD(IER)
IF(IER.NE.0) GO TO 20
C ... process shot ...
LOGICAL LOG
CHARACTER*8 ERRSTR ! receive unrecognized control string
C display menu only if user at tty is in control...
IF(LXOUT(0)) TYPE 1001
1001 FORMAT(' OPTIONS:'/
>' A: PLOT ITEM A'/' B: PLOT ITEM B'/' X: EXIT')
10 CALL UREAD('PROG: ENTER OPCODE:$$')
IOP=IXUOPC('ABX$') ! NOTE "$" TERMINATOR
IF(IOP.EQ.1) THEN
C PLOT A - LINEAR SCALE
LOG=.FALSE.
CALL PLOT('A',LOG)
ELSE IF(IOP.EQ.2)
C PLOT B - USER SPECIFIES LOG/LINEAR
CALL UREAD('PROG: PLOT B ON LOG SCALE? (Y/N):$$')
LOG=LYES(0) ! .TRUE. ONLY IF INPUT WAS "Y"
CALL PLOT('B',LOG)
ELSE IF(IOP.EQ.3) THEN
C EXIT
RETURN
C UNKNOWN OPTION
ELSE
CALL CDCOD(ERRSTR)
CALL UERMSG('%PROG: UNKNOWN OPTION',ERRSTR,0)
ENDIF
C
GO TO 10
The UREAD typeahead buffer has length 512 characters.
If the application program declares a string STR it can be loaded
with the current typeahead buffer contents via:
CALL URDBUF(STR,LEN,0)
in which case LEN returns the lesser of: the length of STR or the
address of the last nonblank character of the typeahead buffer as
copied into STR.
CALL URDBUF(STR,LEN,1) will fetch the buffer with the item
most recently rotated out of the buffer restored.
I use URDBUF to fetch the buffer for output when reporting error
conditions.
Use of URDBUF instead of standard decoding calls to analyze user
input is not recommended. But if this is desired, the application
must manage the typeahead buffer. Use
CALL UCLEAR ! to flush the buffer after error
CALL UROTOR(ic) ! to "rotate" ic characters out of the buffer
after successful decoding; follow with another call to UREAD or
URDBUF.
(if the typeahead buffer is not properly managed, then, input may
be lost, or, processed more than once).
If an application does not require the flexibility in decoding input
that is provided by the seperated CALL UREAD / call decoding function
approach described in the previous submodule, a simple alternative is
available: combined calls, which both send the UREAD prompt and decode
the response. These calls are available:
CALL UREADI(prompt,I) ! send prompt, retrieve integer I
CALL UREADF(prompt,F) ! send prompt, retrieve real no. F
CALL UREADR8(prompt,FF) ! send prompt, retrieve REAL*8 FF
! for the following, character strings are returned in UPPERCASE:
CALL UREADC(prompt,C) ! send prompt, retrieve character*1 C
CALL UREADW(prompt,W) ! send prompt, retrieve word (char*n) W
CALL UREADL(prompt,L) ! send prompt, retrieve line (char*n) L
! difference btw. UREADW and UREADL is that UREADW returns
! a "word" (terminated in the input buffer by a blank or
! comma); UREADL returns the entire typeahead buffer in L.
! the following calls return strings in the case as typed in by the
! user:
CALL UREADLC(prompt,C) ! send prompt, retrieve character*1 C
CALL UREADLW(prompt,W) ! send prompt, retrieve word (char*n) W
CALL UREADLL(prompt,L) ! send prompt, retrieve line (char*n) L
! no case conversion performed!
The "prompt" argument is the same as in the basic UREAD call.
The initial value of the variable argument (I or F or ...) is displayed
as the default value. If the user specifies "," as input the default
value is retained. For compatibility with old codes UREADI and UREADF
also accept "Q" on input as a request to retain the default.
The default value feature does not apply to the UREADL and UREADLL
calls.
See also the section on TIC emulation.
A TIC-style interface to UREAD is available. The FORTRAN calls are
as documented in TFTR-S1801,
"Using the Terminal Interactive Control (TIC) Package",
available from CICADA documentation. Exception-- HEX and double-
precision read calls are not provided. (Author's note-- I will
generate these if anybody really needs them). This TIC interface
provides a handy alternative "style" for using UREAD. It also makes
it easy to convert codes already using TIC to use UREAD.
Note1: The TIC interface routines are in a seperate object library on
the VAX-- see the section on loading instructions.
Note2: The USER interface to UREAD/TIC programs is UREAD, not TIC.
The TIC emulator routines simply CALL UREAD and decode. TIC "/"
commands will NOT work-- but UREAD syntax provides equivalent
functionality and more: see description of the UREAD user interface.
UREAD terminal control has two aspects:
(A) suppression of menu/ explanatory output to the terminal when the
typeahead buffer is not empty or an input file rather than terminal
input is controlling the applications program (to speed program
execution; however the UREAD command *E (echo debug) restores all
messages). The applications program must follow a coding rule to
gain this feature.
(B) physical terminal dependence (i.e. different page clear
instructions if terminal is an ADM rather than Tektronix). The
applications program will run faster on certain terminals if coded
with terminal dependence in mind. A VAX/VMS logical name must be
defined in order to tell UREAD programs what kind of terminal is
being used.
The UREAD logical function LXOUT returns .TRUE. if
(a) a user at a terminal is in control of the applications program
and the typeahead buffer is empty, or
(b) the echo switch is set with the UREAD *E command.
Conversely LXOUT returns .FALSE. if *E is not set and
(a) the typeahead buffer is not empty (i.e. the next n prompts have
been anticipated and the answers provided), or
(b) a UREAD indirect input file is controlling the program.
The UREAD integer function LNOUT(0) returns the LUN of the tty for
output (it is always 6). So, to suppress output of menus and
explanatory messages under these conditions, use LXOUT ...
LUNT=LNOUT(0)
...
C display menu (only if user at tty is in control)
IF(LXOUT(0)) WRITE(LUNT,format) ...
throughout the applications program.
Here UREAD's age shows -- reference to ancient CRT/user terminal
brands dating to before the era of PCs!
UREAD uses the library TERMCTL by Harry Towner to generate terminal
dependent page clears and switching between Tektronix emulation and
text modes. The VAX/VMS process logical name (or UNIX environment
variable) TERMINAL_TYPE should be assigned the value:
V550 for a V550 type terminal
TK40nn for a Tektronix terminal
ADM or ADMxx for a retro-graphics ADM terminal.
MAC for a Macintosh running Versaterm
XTERM for a (Unix-based) "xterm" terminal emulator.
UPDATE:
If the logical name is not defined (or the definition is not known),
UREAD assumes "XTERM". This is usually correct, except for a few
die hard MAC Versaterm-PRO users still out there (dmc March 2004).
LOGICAL L
L=LXOUT(0) ! .TRUE. to write menu or explanatory message
LUNT=LNOUT(0) ! LUN for output on tty (always 6)
C NEUPAG is required for Tektronix as the text screen does not scroll...
CALL NEUPAG ! terminal dependent page clear - leaves terminal
! in text mode (not Tektronix mode) if available.
CALL UPAUST(0) ! "text mode" UPAUSE - rings bell and requires
! acknowledgement (e.g. of an error)
CALL UPAUST(1) ! "text mode" UPAUSE - UPAUST(0) plus a page clear
! UPAUST require user acknowledgement if a tty
! is attached to the job; it has no effect on
! BATCH jobs.
C
C GRAPHICS (SG) RELATED CALLS (suggested usage)
CALL UINITA(0) ! initializes SG (INITT) as well as UREAD COMMON
! block. sCALL once at very start of application.
CALL UBINIT ! before each graph. terminal-dependent transition
! to Tektronix mode. SG BINITT CALL generated.
CALL UPAUST(2) ! after each graph. Generates SG CALL UPAUSE(0)
! rings bell, user acknowledges graph (if graph
! went to a tty). Terminal dependent transition
! to text mode.
CALL UEXITA(0) ! exit program. SG CALL FINITT. STOP.
C ALL WORK OK WITH BATCH JOBS OR GRAPHICS OUTPUT TO DISK FILE (NOT TTY)
CALL UINITA(ILUN) (or CALL AT_INIT0 (TIC)) initialization, INITT call
CALL USINIT initialization, no SG INITT call
CALL UEXITA(0) exit (w/ page clear and SG FINITT call)
CALL UREAD('prompt$') get data (general purpose call)
I=IDCOD(IER) F=FDCOD(IER) FR8=R8DCOD(IER) CALL CDCOD(word)
L=LYES(0) L=LYESC(char) L=LCHAR(char) L=LWORD(word)
I=IXUOPC('str$') I=IXUOPW(list,n)
decode data or see if character input matches expected char or word
CALL UREADI(prompt,i) CALL UREADF(prompt,f) CALL UREADC(prompt,char)
CALL UREADW(prompt,word) CALL UREADL(prompt,line)
CALL UREADR8(prompt,fr8) ...these calls combine the prompt send
and the data retrieve functions
all TIC calls AT_REAL, AT_CMERR, etc. in USR:[UFILES]URTIC.OLB
L=LXOUT(0) LUNT=LNOUT(0) CALL NEUPAG CALL UBINIT
CALL UPAUST(iarg) terminal control routines
CALL UERMSG(msg,word,tty_code) CALL UERMSI(msg,i,tty_code)
CALL UERMSF(msg,f,tty_code) error message routines
CALL UCLEAR flush typeahead buffer e.g. after error
CALL URDCMI('command string') execute certain UREAD commands
CALL URDTTI('insert string') insert string in typeahead buffer
When a UREAD application program encounters an error, two things
need to happen:
(1) some kind of report of the error to the terminal;
(2) flush the typeahead buffer, so that the user gets control
at the first prompt following the error; for example:
10 CALL UREADW('PROG: ENTER FILENAME:$$',FILENAM)
CALL GETFIL(FILENAM,IER)
IF(IER.NE.0) THEN
TYPE 9001,FILENAM
9001 FORMAT(' %ERROR READING DATA FOR FILE ',A)
CALL UCLEAR ! flush typeahead buffer
GO TO 10
ENDIF
20 CALL UREAD('PROG: SPECIFY FILE DATA PROCESSING OPTION:$$')
"CALL UCLEAR" flushes the typeahead buffer. In this code example
failure to do this would cause any typeahead beyond the filename,
intended for the prompt at line 20, to be interpreted incorrectly
at line 10 as another filename.
Several calls are available to combine the error message and buffer
flush, with additional terminal control options.
CALL UERMSG(msg,char_arg,itty_opt)
CALL UERMSI(msg,integer_arg,itty_opt)
CALL UERMSF(msg,real_arg,itty_opt)
the first argument msg is the error message; the second item is
encoded and written out to suppliment the error message (may be
blank in UERMSG); the third argument has these optional values
for terminal control:
0 for no action
1 for UPAUST(0) ring bell/ user acknowledge call after message
2 for UPAUST(1) call (with page clear) after message
-1 for page clear (CALL NEUPAG) BEFORE message
see section on terminal control for info on UPAUST and NEUPAG.
The following TIC calls are in the UREAD TIC emulator library and
might be useful for error handling:
AT_PAUSE (ring bell, user acknowledge)
AT_MSGE(msg) (send message to terminal, unconditionally)
AT_ERROR(icode,msg) (send error message with error code no. to tty)
AT_CMERR(icode,msg) (send error message and generate CM (CICADA
keyword file system) error message)
AT_RESET (flushes typeahead buffer)
These routines perform as described in the TIC documentation.
The following calls modify UREAD characteristics
CALL USINGL disables typeahead. buffer flushed on each UREAD
call.
CALL UAHEAD re-enables typeahead (restores the default).
The following are not recommended: use UREADL and UREADLL instead.
The description here is for historical purposes in case any very
old user UREAD code is still out there...
CALL URDMOD(2) enters "text" mode. UREAD typeahead, upper-
case conversion, and input left-justification
are all suppressed. Use this e.g. with
CALL UREADL('$',line) to read lines verbatim
from the terminal.
CALL URDMOD(1) restores the default, UREAD "command" mode.
CALL URDMOD(0) UREAD "command" mode, but, uppercase conversion
of input is suppressed. Useful e.g. for unix
filename input.
Note -- in the 2004 version of UREAD, there is no longer any difference
between CALL URDMOD(0) and CALL URDMOD(1).
CALLs of the form CALL URDCMI('command string') allow execution of
some UREAD commands (normally typed in at a terminal) from within the
application program:
CALL URDCMI('/name=value') defines a UREAD string parameter.
CALL URDCMI('*E') executes a command: turn on echo. Most "*"
commands are available to URDCMI.
CALL URDCMI('>proglog.ind') opens an output file "PROGLOG.IND"
which will record program prompts and user replies. This
should be done just after initialization (CALL UINITA(i)),
if at all, or it might interfere with a user's attempt to
create automated indirect files for the program. A message
informing the user of the existance of the opened file is
issued and the user may close the file by typing ">".
URDCMI cannot be used to open input files or modify the way an input
file will be read, nor can it modify the typeahead buffer. It can be
used to define a string parameter which can be checked by the UREAD
indirect input file (e.g. set a parameter to be used as an error flag).
For more info on UREAD commands, see help on the user interface.
The applications program may access the value of a UREAD string
parameter with a call of the form
CALL USPGET(NAME,VALUE,IER)
where:
CHARACTER*16 NAME is the left justified, blank padded uppercase
parameter name input.
CHARACTER*48 VALUE is the 48 character blank padded value returned
IER is the completion code: 0=success, 1=error (probably the name
is not known).
The applications program may define UREAD string parameters using the
URDCMI callable command facility described under "Callable_commands".
For more info on UREAD string parameters, see help on the user
interface.
An applications program may write access the input typeahead buffer
with a call of the form
CALL URDTTI('insert string')
where "insert string" is any character string which (the applications
programmer hopes) will make sense to his/her own program when it is
subsequently decoded as input. The string is inserted at the head
of the buffer ahead of any pending user input. If the user input is
to be overwritten, precede the URDTTI call with a CALL UCLEAR to flush
the typeahead buffer.
Because any UREAD or applications program instruction can be inserted
via URDTTI, this is a powerful but dangerous call whose use should
be carefully thought out in advance. It is used internally in UREAD
to reconstruct the typeahead buffer when certain parsing functions yield
negative results.
A possible use for URDTTI in an applications program might work as
follows: if the application uses the input character "Q" to back out
of all menu or prompt nodes to return to a higher level node, except at
the highest level or "root" node, where "Q" is ignored and "X" is
required to exit, then CALL UCLEAR/ CALL URDTTI('QQQQQQQQQQ') will
return control to the highest level node in the program (if the current
position in the node tree structure is no more than ten levels deep).
>>> USE CTRL(S) CTRL(Q) - THIS IS A 50 LINE MODULE
C-----------------------------------------------
C PROG a hypothetical UREAD program
C
PROGRAM PROG
C
C READ, PLOT DATA
C
PARAMETER NMAX=2048
REAL X(NMAX),Y(NMAX)
CHARACTER*8 TEST ! TEST STRING IN CASE OF ERROR
C
C INITIALIZE CONTROL INPUT - ALLOCATE UNITS 90 THRU 98 TO FILE STACK
C note SG INITT also called...
CALL UINITA(90)
C
10 CONTINUE ! DATA TYPE LOOP
C TYPE EXPLANATION IF USER AT TTY HAS CONTROL
IF(LXOUT(0)) TYPE 1001
1001 FORMAT(' THERE ARE THREE DATA TYPES, A, B, C, FOR EACH SHOT')
C GET DATA TYPE SPECIFICATION
CALL UREAD('PROG: ENTER DATA TYPE (A B OR C) OR "Q":$$')
C EXIT PROGRAM?
IF(LCHAR('Q')) CALL UEXITA(0) ! STOP PROGRAM; SG FINITT CALL
C A,B, OR C? ("LCHAR" CALL DID NOT AFFECT TYPEAHEAD INPUT BUFFER)
ITYPE=IXUOPC('ABC$')
IF(ITYPE.EQ.0) THEN
C UNKNOWN TYPE... GET USER INPUT, REPORT ERROR, FLUSH BUFFER, RETRY
CALL CDCOD(ZTEST)
CALL UERMSG('%PROG: UNKNOWN DATA TYPE:',ZTEST,0)
GO TO 10
ENDIF
C GET SHOT NUMBER-- FACILITATE LOOP OVER SEVERAL SHOTS...
20 CONTINUE ! SHOT LOOP
CALL UREAD('PROG: ENTER 5 DIGIT SHOT NO. OR "Q" TO QUIT:$$')
IF(LCHAR('Q')) GO TO 10 ! CHECK FOR "Q"
C DECODE SHOT NO.
ISHOT=IDCOD(IER)
IF(IER.NE.0) GO TO 10 ! IDCOD REPORTED ERROR (IF ANY)
C hypothetical data read routine:
CALL GETDATA(ISHOT,ITYPE,X,Y,NMAX,NGOT,IER)
IF(IER.NE.0) THEN
C REPORT ERROR AND FLUSH BUFFER BEFORE TRYING ANOTHER SHOT
CALL UERMSI('%PROG: COULD NOT ACCESS DATA FOR SHOT',ISHOT,0)
GO TO 20
ENDIF
C PLOT DATA
CALL PLOTDATA(ISHOT,ITYPE,X,Y,NGOT)
C TRY ANOTHER SHOT
GO TO 20
END
C---------------------------------------------------------
C PLOTDATA hypothetical routine using UREAD: PLOT THE DATA
C
SUBROUTINE PLOTDATA(ISHOT,ITYPE,X,Y,N)
REAL X(N),Y(N)
CHARACTER*8 TEST ! TEST STRING IN CASE OF ERROR
C
C PREPARE SCREEN FOR PLOT (SG BINITT CALL PLUS TERMINAL DEPENDENCE)
10 UBINIT
C PLOT THE DATA: ISHOT, ITYPE FOR LABEL
CALL DRAWDATA(ISHOT,ITYPE,X,Y,N) ! hypothetical subroutine
C GET USER ACKNOWLEDGEMENT (SG UPAUSE CALL PLUS TERMINAL DEPENDENCE)
CALL UPAUST(2)
C OPTION MENU AFTER PLOT-- DISPLAY ONLY IF USER AT TTY IN CONTROL
20 IF(LXOUT(0)) TYPE 1002
1002 FORMAT(/' REPLOT OPTIONS:'/' A: CHANGE AXES TYPES (LOG/LIN)'/
>' S: CHANGE PLOT SCALE'/' X: EXIT')
CALL UREAD('PLOTDATA: ENTER REPLOT OPCODE (ONE LETTER):$$')
C TEST INPUT. TYPEAHEAD BUFFER INPUT "ROTATED OUT" ONLY WHEN
C THE TEST (LCHAR) RETURNS .TRUE.
IF(LCHAR('A')) THEN
CALL AXES ! hypothetical routine SET AXES TYPES
GO TO 10
ELSE IF(LCHAR('S')) THEN
CALL SCALE ! hypothetical routine SET SCALE
GO TO 10
ELSE IF(LCHAR('X')) THEN
RETURN ! EXIT
ELSE
C RETRIEVE UNRECOGNIZED INPUT CODE, REPORT ERROR, FLUSH BUFFER, RETRY
CALL CDCOD(TEST)
CALL UERMSG('PLOTDATA: RESCALE OPTION NOT KNOWN',TEST,0)
GO TO 20 ! REPROMPT W/ MENU DISPLAY
ENDIF
END
Applications programs which use UREAD for input may be conveniently
interfaced to DCL as "foreign commands". To do this, one defines a
symbol pointing at the program image file, e.g.
$ PROG :== $RX99:[USER.PROGRAMS]PROG.EXE
(more info available on foreign commands). Then one may invoke PROG
simply by typing
$ PROG
instead of the more complicated
$ RUN RX99:[USER.PROGRAMS]PROG
Even better than this, if CONTROL.IND is a UREAD input file which
contains command input for PROG,
$ PROG @CONTROL.IND
will run PROG and turn control over to CONTROL.IND, direct from DCL.
Even better yet, if NSHOT is a UREAD parameter used in CONTROL.IND,
and SHOT_NUM is a DCL symbol, then
$ PROG @CONTROL.IND/NSHOT='SHOT_NUM'
will run PROG under control of CONTROL.IND with the value of SHOT_NUM
supplied as the value of NSHOT.
Thus the foreign command mechanism provides a communications window
between the DCL control language and the UREAD control language. This
permits creation of batch jobs using UREAD programs with enhanced
flexibility of control.
For information on how to create UREAD control files like CONTROL.IND
and how to pass multiple parameters, see key User_Interface.
Foreign commands are a VMS/DCL feature. The definition
$ PROG :== $RX99:[USER.PROGRAMS]PROG.EXE
creates PROG as a foreign command. Foreign commands are usually
defined in a LOGIN.COM file or subprocedure.
The leading "$" immediately preceding the disk name identifies this
symbol as a DCL foreign command. A full pathname for the image file
including disk and directory MUST be supplied, although a logical name
may be substituted, i.e.
$ ASSIGN RX99:[USER.PROGRAMS] EXE_AREA
$ PROG :== $EXE_AREA:PROG.EXE
is correct, but
$ PROG :== $PROG.EXE ! don't do this !
will NOT work even if your DCL first says
$ SET DEFAULT RX99:[USER.PROGRAMS]
On UNIX systems, UREAD executables are made commands simply by putting
the program executable file in a directory that is found in the users
PATH environment variable -- i.e. the usual UNIX procedure.
Any command line arguments are supplied to the program as if they
were typed in by the user in response to the first UREAD prompt.
Thus for example
rplot @foo
will cause the "rplot" program to be launched under the control of
the UREAD script foo.tmi ... the extension ".tmi" being the script
extension for the TRANSP rplot display program.
On PPPL unix systems (other than LINUX):
(no SGLIB graphics):
-L/usr/ntcc/lib -lureadsub -lsgdummy -lvaxonly -lportlib
(with SGLIB):
-L/usr/ntcc/lib -lureadsub -lsg -lvaxonly -lportlib
Add -lreadline -lhistory -ltermcap
if portlib was built with line editing option.
On PPPL LINUX systems:
It depends on what fortran compiler you are using! The /usr/ntcc
directory contains subdirectories for PPPL's commonly used fortrans:
lff95 -- Lahey Fujitsu
pgf90 -- Portland Group
ifc -- Intel
So for example, with Lahey Fujitsu:
(no SGLIB graphics):
-L/usr/ntcc/lff95/lib -lureadsub -lsgdummy -lvaxonly -lportlib \
-lreadline -lhistory -ltermcap
(with SGLIB):
-L/usr/ntcc/lff95/lib -lureadsub -lsg -lvaxonly -lportlib \
-lreadline -lhistory -ltermcap
the use of the "command line editing" libraries is highly recommended
on unix. These allow the same command line recall and editing features
(emacs style) that is available in the more modern unix shells like
bash and tcsh.
Note to Non-PPPL UNIX sites:
Verify above directory names with your systems administrator.
On old PPPL VMS systems:
UREAD and associated routines are contained in the subroutine library
USR:[UFILES]GFLIB.OLB. Two additional libraries are needed: SGLIB
and TERMCTL, to support various terminals at the laboratory. To link
your program (PROG),
$ LINK PROG,USR:[UFILES]UFILES/OPT
This invokes a linker "option" file which will bring in all the objects
needed to complete a program which utilizes UREAD. The "option" file
points to the libraries GFLIB, TERMCTL, and SGLIB. It also points to
UFLIB and SMLIB, the UFILES and smoothing utility libraries. Only the
routines needed are mapped in to complete your link.
If you want the UREAD TIC emulation library USR:[UFILES]URTIC/LIB, you
must LINK it in explicitly. This is to avoid accidental conflicts
with the alternative TIC emulation set in John Coonrod's CMLIB library.
URTIC contains a complete set of TIC ("AT") calls, as documented in
TFTR-S1801, "Using the Terminal Interactive Control (TIC) Package",
except for the HEX and DBL double precision real input routines.
Please contact the author, D. Mc Cune for suggestions re. UREAD
or this HELP file. pppl x2731. send mail to dmccune@pppl.gov ...
However (obviously) UREAD is truly ancient legacy software. So,
major upgrades are not contemplated.
This Document was created by hlptohtml
Written By:Manish Vachharajani(mvachhar@pppl.gov)