1 UREAD 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 generally interpreted as responses to the earliest program prompts (this behavior can be overridden). 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. 2 Terminology UREAD documentation frequently refers to "indirect input files". These are really control scripts, which have a generic format ;$ answer... ;$ 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. 2 Prompt_mismatch 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. 2 User_Interface 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". 3 History [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. 3 Benefits Applications programs use UREAD with the simple call CALL UREAD('$') Where 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. 4 Code_developement/automation 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. 4 Modular_control 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. 3 Function_of_UREAD_CALL 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". 4 Discription_of_UREAD_execution 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. 4 Diagram_of_UREAD_execution 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. 3 Execution_of_UREAD_program (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. 4 UREAD_INI_environment_variable 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. 3 Typeahead 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. 4 word_delimiters 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. 5 quote_string_words *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 4 Example 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. 3 Commands 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 [] - stop (ABORT) the program with message (if terminal is attached, user is prompted for verification). *C [] - 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 . Specified file 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 - 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 * is not a command it is returned to main program) *U 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). 3 Parameters 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. 4 parameter_types_local_or_global 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 /= space for 20 parameter definitions are reserved for each input file. global parameter definitions have the form /== 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.: /==/ addl. typeahead stuff... 4 substitution_of_parameters 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. 5 substitution_inside_double_quote_strings 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. 5 examples 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. 4 Arithmetic_with_parameters Primitive arithmetic may be performed on parameters which are decodable as integers. The syntax is /=.+ which causes the amount to be added to the value of the parameter with name . Note the dot "." is necessary to dis- tinguish an arithmetic operation from merely assigning the value "+" 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. 4 Caveats Typically, the interpretation of "/" for parameter definition or parameter value substitution is suppressed, at program prompts which request a unix filename (to avoid confusion with use of "/" in unix file path designations). 3 Files 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. 4 Output_files UREAD output files are opened when an input line of the form ">" is encountered. The special character ">" indicates "open a UREAD output file". does not include an .ext extension, a default extension is supplied. Typeahead in the form > 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 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. 5 Example 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. 4 Input_files A UREAD indirect input file is invoked with a line of the form @ If in the filename extension .ext is omitted, a default .ext is supplied. The text lines in the file 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: @ However, the input after the "@" is deferred and will not be executed until after the instructions in file are completed. A new, empty typeahead buffer is allocated to the newly opened file. 5 Prompt_match_checking 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. 6 $MATCH 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. 4 File_stack 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. 4 Parameter_passing 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: @/name1/name2/name3=value3/ results in parameters "name1", "name2", "name3" being inserted in the local parameter table for the file (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 terminates "value3" and the parameter passing fields; is retained in the typeahead buffer attached to the file from which 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 ">". 3 Comments 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. 3 Branching 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 where is the name of a target label (see definition). A conditional transfer has form: ?="" SKIPTO or ?#"" SKIPTO where is the name of a UREAD parameter (see definition), "=" or "#" are logical operators (equals or not equals, respectively), and "" is the test value with which the value of is compared to determine whether or not to execute the SKIPTO branch. The existence of a defined parameter can also be tested: ?DEFINED() SKIPTO or ?UNDEFINED() SKIPTO It should be noted that, normally in the UREAD world, if an undefined parameter is encountered, the user is prompted to provide a value. However, the tests ?DEFINED(...) and ?UNDEFINED(...) allow the programmer to build scripts to handle undefined variables explicitly. A note of caution: the uread script handler substitutes parameter values before parsing. So, the input line "?DEFINED(FOO) *T FOO = 'FOO'" will prompt for a value of FOO **before** the ?DEFINED(FOO) test is carried out, so that the inline substitution 'FOO' can be done. To avoid this, put the output operation "*T" on a separate line, as in: ?UNDEFINED(FOO) SKIPTO FOOSKIP *T FOO = 'FOO' :FOOSKIP The effect of this is to print the line "FOO = ", if the parameter is defined, or, no action if the it is not defined. 4 branching_continued 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: ?="" results in being processed as input only if the test is satisfied; otherwise the typeahead buffer is flushed and the next input line is read. Similarly: ?DEFINED() ...results in being processed, only if is defined (regardless of its value). or the opposite: ?UNDEFINED() 4 example The following sequence of records might appear in an indirect input file: ;PROG>AVERAGE THE DATA (Y/N):$ ; this is the program prompt ?UNDEFINED(AVER_FLAG) *T Expected parameter AVER_FLAG is undefined. ?UNDEFINED(AVER_FLAG) SKIPTO EXIT ?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' ... ... :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). 4 Target_of_branch When a SKIPTO is encountered, UREAD reads sequentially through the input file looking for a line which starts with : 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 : (i.e. typeahead past a marker is legal). 4 Looping 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 5 Generic_loop_file (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==/S2==/ ... /S==/S==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, ... 3 Actual_examples On VAX and UNIX systems at PPPL the UREAD system is actually used in many applications. Here are some examples: 4 Plotting_TRANSP_output. 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). 4 Preparing_Data_for_TRANSP_input 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. 4 Translation_of_TFTR_YS_data (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. 3 Summary 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. 2 FORTRAN_Interface 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. 3 CODE_PORTABILITY (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. 3 Initialization 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). 4 Variations 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. 3 UREAD_subroutine_call 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. (Uread variants that allowed prompt and answer to appear on the same line have been removed, because of portability issues). 4 Prompts 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. 4 Null_prompts 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). 3 Data_decoding 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. 4 More_decoding_calls 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) 4 General_information 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. 4 Usage_examples 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). 5 A_Example 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 5 B_Example 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 ... 5 C_Example 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 4 Typeahead_buffer_access 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). 3 Combined_calls 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! ! NOTE: UREADLW is usually used to retrieve filenames. To avoid problems with unix paths, it suppresses interpretation of "/" as a parameter assignment or parameter retrieval special character. Parameter substitution can still be done using "'" or "{,}", but parameter assignment cannot be done in the user response to UREADLW. 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. 3 TIC_interface 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. 3 Terminal_control 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. 4 A_Aspect 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. 4 B_Aspect 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). 4 Terminal_control_calls 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) 3 CALL_summary 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 3 Error_handling 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. 4 Error_message_calls 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. 4 TIC_error_handling_calls 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. 3 Modifications 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). 3 Callable_commands 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. 3 Parameter_access 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. 3 Typeahead_access 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). 3 FORTRAN_example >>> 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 4 PLOTDATA_SUBROUTINE 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 2 VMS_DCL_command_interface 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. 3 foreign_command 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] 2 Unix_command_line 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. 3 Arguments_not_for_Uread The command line argument "-!" instructs UREAD to stop interpreting command line arguments (so that such arguments can be used for some other purpose). Thus, if "prog" is a UREAD program: prog a b c -! d e f Then UREAD will use "a b c" only. To get the indices of non-uread arguments, this call provides the necessary information: call uread_arg_count( nargu, nargc ) In the above example, nargu=4 and nargc=7 would be returned; the first four arguments including the delimitting "-!" are used by UREAD; argument indices nargu+1:nargc are available for parsing by other means. (This feature added by Jim Conboy at JET, June 2010; commentary by D. McCune, June 2010). 2 Loading_Instructions On PPPL unix systems (other than LINUX): (no SGLIB graphics): -L${NTCCHOME}/lib -lureadsub -lsgdummy -lvaxonly -lportlib (with SGLIB): -L${NTCCHOME}/lib -lureadsub -lsg -lvaxonly -lportlib Add -lreadline -lhistory -ltermcap if portlib was built with line editing option. On PPPL LINUX systems: We use "module" to load software. First load a fortran compiler. Then "module load ntcc". So for example, with SGLIB: -L${NTCCHOME}/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. 2 Suggestions_to_author 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.