Argonne National Laboratory Applied Mathematics Division COMMAND LINE SUBROUTINES FOR RSX-11M FORTRAN April 1982 Martin R. Kraimer Abstract This manual describes a number of Fortran command line subroutines that allow a Fortran programmer to quickly and easily write interactive programs for the RSX-11M operating system. RSX-11M is an operating system for the Digital Equipment Corporation (DEC) PDP-11 series of computers. These command line subroutines provide terminal input/output and syntax analysis capabilities. The terminal I/O subroutines support indirect command files that can contain imbedded prompt strings. They also provide TRACE, HELP, and LEARN support. The syntax analysis subroutines are designed to process input lines obtained from indirect command files or from a terminal. CHAPTER 1 INTRODUCTION The subroutines described in this manual allow a programmer to quickly and easily write interactive programs. The routines can be used both for "command language" and for "menu-type" programs. Simple examples of each type of program are given later in this manual. The subroutines have been written for use under the PDP-11 RSX-11M operating system, and are compatible with the Fortran-IV, Fortran-IV-Plus, and the Fortran-77 compilers. The subroutines can be divided into the following classes: 1. Terminal I/O 2. Syntax Analysis 3. Character String Manipulation 4. Command Processing Terminal I/O Subroutines ________ ___ ___________ The terminal I/O subroutines interact with the terminal. The PROMPT subroutine prompts for and obtains input from a terminal. PROMPT allows indirect command files, processes three special commands (TRACE, LEARN, and HELP), and allows prompt strings to be imbedded within indirect command files. When TRACE is on, each line taken from an indirect command file is displayed on the user's terminal. When LEARN is active, all lines entered by the user are saved in a file that can later be used as an indirect command file. HELP invokes the RSX-11M HELP processor. Indirect command files can have imbedded prompt strings. When PROMPT finds an imbedded prompt string, it prompts the user at his terminal and replaces the prompt with the user's response. The PLINE subroutine writes on the user's terminal. USIBEG and USIEND allow the calling program to process unsolicited terminal input. This is useful for programs that produce long listings, etc. By using USIBEG and USIEND, the program can allow the user to interrupt the program without INTRODUCTION Page 1-2 aborting the program. Syntax Analysis Subroutines ______ ________ ___________ Syntax analysis subroutines are used to perform syntax analysis. The TOKEN subroutine locates the next token in the current input line. The token types are null (i.e., a leading comma), end-of-line, empty line, octal integer, decimal integer, floating-point number, name, and special character. The SYNERR, (Syntax Error) subroutine displays the current input line with the previous token replaced with question marks. It can be used to show the user exactly where he made an error. Character String Manipulation Subroutines _________ ______ ____________ ___________ Character string manipulation subroutines provide the Fortran programmer with a basic set of routines to perform character string manipulation. They are used extensively by the other subroutines described in this manual. Command-Processing Subroutines __________________ ___________ The command-processing subroutines makes it a little easier to write command-processing programs. The command line routines communicate with each other and with the program using them through common block CLP. CLP must be thoroughly understood before the user can understand and use the subroutines described in this manual. CLP is listed in Appendix A. Let's briefly describe the variables in CLP. TYPNUL, TYPEOL, TYPEL, TYPINT, TYPFLT, TYPNAM, and TYPSPC are the token types recognized by subroutine TOKEN. TLU is the terminal logical unit. Any subroutine can perform input or output to this logical unit. CLPEFN is an event flag usable by any routine that does an immediate wait on this event flag. In particular, it is used by subroutine PROMPT. CNTLZ is a logical variable that is set true when PROMPT detects an end-of-file in the level 0 indirect command file or when the user types CNTL/Z. This is a signal that the program should clean up and exit. TRACE is set if trace mode is in affect. PROMPT uses this to decide if prompts and input lines should be echoed to the user's terminal. NXTCHR is a variable that points to the next character of LINE not yet processed by TOKEN. INTRODUCTION Page 1-3 TOKLEN is the length of the previous token processed by TOKEN. TOKTYP is the type of the previous token processed by TOKEN. INTVAL, FLTVAL, STRVAL, and CHRVAL are the integer, floating-point, string, and first-character values of the previous token processed by TOKEN. USICHR is the most recent character trapped by the unsolicited terminal input routines. This variable is described with the USIBEG and USIEND routines. CHAPTER 2 TERMINAL I/O SUBROUTINES This chapter describes six routines: PROMPT, PLINE, GCML, USIBEG, USIEND, and USIAST. PROMPT is responsible for getting the next line of input. PLINE sends an output line to the user's terminal. GCML is an assembly language interface used by PROMPT that provides access to the RSX-11M command-line processing subroutines (described in the RSX-11M _______ I/O Operations Manual). USIBEG and USIEND are used to process ___ __________ ______ unsolicited terminal input. USIAST is an assembly language routine used by USIBEG. First, we'll describe the services provided by these subroutines, and then we'll summarize the algorithms used by each subroutine. 2.1 Use of PROMPT Subroutine Whenever a program wants a new line of terminal input, it issues the following Fortran statement: CALL PROMPT(STR) STR is a character string that is used to prompt the operator for input taken from the terminal. If the input is taken from an indirect command file, STR is ignored. If STR is not a null string, a "?" is appended to the end of STR. The characters tsk>, where tsk is the first three characters of the task name, are always put before STR. Note that a zero parameter will be accepted as a null string. As examples, assume that the task name is "TST". If the call is CALL PROMPT(0) then the operator will be prompted TST> If the call is CALL PROMPT('COMMAND') the prompt is TERMINAL I/O SUBROUTINES Page 2-2 TST>COMMAND? 2.1.1 Using Indirect Command Files PROMPT, in conjunction with GCML, provides support for indirect command files. If input is being taken from indirect command files, STR is ignored. GCML is initialized to provide support for three levels of indirect command files. Indirect command files can be invoked in three ways: 1. As a parameter on an MCR command line. 2. In response to a prompt from PROMPT. 3. As a line in an indirect command file. An example of the first method, a parameter on an MCR command line, is: >TST @filename TST must be an installed task for this to work. If an indirect command file is invoked this way, CNTLZ will be set true when an end-of-file is detected in file "filename". Thus, unless an indirect command file has imbedded prompt strings, program TST will run to completion without any operator intervention. Thus it is possible to write indirect command files containing requests to run tasks which call PROMPT. The second method of invoking an indirect command file is to specify an indirect command file in response to a prompt issued by PROMPT. For example, TST>@filename If this case, each call to prompt, beginning with the initial call, causes a line of input to be read from file "filename". This continues until an end-of-file is detected in file "filename". At this point, a prompt is written to the terminal and input is accepted from the terminal. CNTLZ will be set only when the operator enters CNTL/Z. The last way to invoke an indirect command file is to invoke it from another indirect command file. For example, a line of an indirect command file can be @filename Note that GCML allows only three levels of indirect command files. For more details about indirect command file processing, consult the RSX-11M _______ I/O Operations Manual. ___ __________ ______ TERMINAL I/O SUBROUTINES Page 2-3 2.1.2 Using TRACE, LEARN, and HELP Commands Upon receiving an input line, PROMPT checks to see if the line begins with the commands "TRACE", "LEARN", OR "HELP". If so, the command is processed and PROMPT begins again. Thus the calling program is not aware that the command has been processed. The TRACE command switches the state of the CLP variable TRACE. TRACE is initially off. The first TRACE command sets it on, the next TRACE command sets it off, etc. When TRACE is on, PROMPT echos all prompts and input lines. The LEARN command is used to create indirect command files. LEARN mode is either on or off. Initially it is off. The first LEARN command turns it on, the second turns it off, etc. When the LEARN mode is turned on, the operator is prompted: FILE NAME? The operator must respond with the name of the file to be created. The default device is "SY:" and the default extension is ".CMD". While LEARN mode is on, PROMPT writes all prompts, preceeded by the character ";", to the file. It also writes all input lines. All TRACE and HELP commands are also written. The HELP command invokes the standard RSX-11M help processor. The first three characters of the task name are inserted after HELP. Thus if the operator types HELP GO The command sent to the help processor is HELP tsk GO where tsk is the first three characters of the task name. Note that the HELP command will only work for installed tasks that have help files on LB:[1,2]. See the RSX-11M MCR Operations Manual for details about _______ ___ __________ ______ creating help files. 2.1.3 Using Imbedded Prompt Strings Whenever PROMPT receives an input line, it looks for imbedded prompt strings. A prompt string is a string of the form "?". Upon finding such a prompt string, PROMPT prompts the terminal with string> and accepts input from the terminal. The entire prompt string is replaced by the terminal input. The input line is repeatedly scanned until no more prompt strings are found. For example, if the original TERMINAL I/O SUBROUTINES Page 2-4 input line is CMD ?,2,? The operator will be prompted twice as follows: ENTER PARM 1> ENTER PARM 2> If the operator responds with the values 25 and 10, then the resultant line will be: CMD 25,2,10 Indirect command files can be created either with a standard editor or by using the LEARN command. If the LEARN command is used, imbedded prompt strings can be placed in an input line. The original line, i.e., the line with the imbedded prompt strings, is written to the LEARN file. The operator will still be prompted for values for the imbedded prompt strings, but the resultant line is not written to the LEARN file. 2.2 Processing Unsolicited Terminal Input If a program performs a function that can take a long time, it is desirable to allow the operator to terminate the function without terminating the program itself. An example is a listing program. The operator might give a list command which results in an extremely long listing. After viewing a part of the list he wishes to stop the listing without aborting the program. The subroutines USIBEG and USIEND allow a program to do this in an easy manner. USIBEG traps all terminal input. The most recent character entered is stored in the variable USICHR, which is located in the CLP named common block. This continues until USIEND is called. The calling program should periodically check the value of USICHR. If it is not zero then the user has entered one or more characters. When USIBEG is called, USICHR is initialized to zero. CTRL/C, CTRL/S, CTRL/Q, CTRL/X, and CTRL/O are not trapped by USIBEG but are handled in the normal manner. A program using USIBEG and USIEND has the following structure: CALL USIBEG loop: IF(USICHR.NE.0)GOTO exit do small amount of processing GOTO loop exit: CALL USIEND Please note that no other terminal I/O routines should be called while USIBEG is active. TERMINAL I/O SUBROUTINES Page 2-5 2.3 Summary of Subroutine Algorithms 2.3.1 Prompt Syntax: PROMPT(STR) When PROMPT starts execution, it first determines whether this is the first call. If it is, PROMPT determines the first three characters of the task name under which is is being executed. PROMPT then constructs the prompt string and calls GCML. GCML returns the input line in LINE, which is a variable in CLP. If GCML detects an end-of-file, PROMPT sets CNTLZ true and returns. If no end-of-file is detected, PROMPT looks for a TRACE, LEARN, or HELP command. If one is found, the command is processed and PROMPT begins again. If none is found, PROMPT looks for imbedded prompt strings. If any are found, they are processed. After all imbedded prompt strings have been processed, PROMPT returns. When prompt returns, the CLP common block is initialized so that the first call to TOKEN will return the first token in LINE. 2.3.2 Put Line Syntax:PLINE(STR) The PLINE subroutine outputs STR to the user's terminal. STR must be a valid character string (any ASCII characters terminated by a zero byte). 2.3.3 Get Command Line The GCML Subroutine is the assembly language interface to the RSX-11M command line processing facilities. It is set to allow three levels of indirect command files. This subroutine is normally called only by PROMPT. GCML also has entry points, RCML and CCML, which invoke the RCML$ and CCML$ routines. See the RSX-11M I/O Operations Manual for _______ ___ __________ ______ more details. 2.3.4 Unsolicited Terminal Input USIBEG calls USIAST. USIAST provides an AST exit which is entered whenever the operator strikes a key on TLU. Each time this happens, the character is moved to CSICHR. USIEND removes the AST exit. TERMINAL I/O SUBROUTINES Page 2-6 CHAPTER 3 SYNTAX ANALYSIS 3.1 Introduction The subroutines described in this chapter help a programmer process input lines obtained by PROMPT. Each time TOKEN is called, it locates and converts the next token contained in LINE. If the program detects an illegal token (a token it is not expecting), SYNERR can be called to show the user the token that was incorrect. TOKEN has no parameters. All communication is performed by using the CLP common block. As an example of what TOKEN does, assume that the input line is: TEST 1,1.0 $,,"100000 The first call to TOKEN will set TOKTYP=TYPNAM and STRVAL="TEST". The second call will set TOKTYP=TYPINT and INTVAL=1. The third call will set TOKTYP=TYPFLT and FLTVAL=1.0. The third call returns TOKTYP=TYPSPC and CHRVAL='$'. The fourth call returns TOKTYP=TYPNUL. The next call returns TOKTYP=TYPINT and INTVAL=-32768. The last call returns TOKTYP=TYPEOL. Note that blanks or blanks and a single comma separate tokens, except for special characters. For special characters, the separators are optional. The description of TOKEN that follows is rather complicated; it is meant to be complete. If you keep the above example in mind, the description should be easier to follow. A serious effort has been made to make TOKEN do "reasonable" things for ambiguous cases. 3.2 Token This routine gets the next token from LINE. TOKEN first decides where the next token begins. It uses the following algorithm to make this decision: 1. If NXTCHR > 1 and LINE(NXTCHR) = "," and the rest of LINE is blank, then TOKEN calls PROMPT and starts all over. SYNTAX ANALYSIS Page 3-2 2. If NXTCHR = 1 and LINE(1) = "," then TOKEN begins with column 1. 3. If NXTCHR > 1 and LINE(NXTCHR) = "," then TOKEN begins with the first non-blank character beginning with LINE(NXTCHR+1). 4. If LINE(NXTCHR) not = "," then TOKEN begins with the first non-blank character beginning with LINE(NXTCHR). 5. If a ";" is detected, the semicolon and the remainder of the line is ignored. These rules allow for the following. 1. If a line ends with a comma, then TOKEN automatically calls PROMPT to obtain another line. 2. If a line begins with a comma, then the first token of that line will have type TYPNUL. 3. If a line has two consecutive commas, then the second will result in a token with type TYPNUL. 4. If a semicolon is detected, the remainder of the line is ignored, that is, it is assumed to be a comment. Note, that if a line begins with a semicolon, the GCML subroutine ignores the line. While processing the next token of LINE, TOKEN sets the following fields in CLP: 1. NXTCHR is set equal to the index of the first character of the token following the token currently being analyzed. It should be noted that a token is terminated by a blank, a comma, or a special character. If a token is terminated by a blank, then NXTCHR will be set equal to the index of the first non-blank character after this blank. If a token is terminated by a non-blank character, then NXTCHR is set equal to the index of this character. 2. TOKLEN is set equal to the number of characters processed in this call to TOKEN. 3. INTVAL, FLTVAL, STRVAL, and CHRVAL are set equal to the converted value of the token. 1. INTVAL is set equal to the integer value of the token if it is a number; otherwise, it is set equal to the smallest possible integer (-32768). SYNTAX ANALYSIS Page 3-3 2. FLTVAL is set equal to the floating value of the token if it is a number; otherwise, it is set equal to 1.0E30. 3. If the token is of type TYPINT, TYPFLT, or TYPNAM, STRVAL is set equal to the character string of which the token is composed; otherwise, STRVAL is set equal to the null string. 4. If TOKTYP is not equal to TYPNAM or TYPSPC, CHRVAL is set equal to a binary 0 (the lowest possible character). If TOKTYP=TYPNAM, CHRVAL is set equal to the first character of STRVAL. If TOKTYP=TYPSPC, CHRVAL is equal to the special character. 4. TOKTYP is set equal to the token type, which may be one of the following: 1. TYPNUL - Either a line begins with a comma, or two consecutive non-blank characters beginning with LINE(NXTCHR) are commas. 2. TYPEOL - no more non-blank characters in LINE. Note that this cannot happen if the last non-blank character in a line is a comma. 3. TYPEL - LINE is initially blank 4. TYPINT - token is a valid FORTRAN INTEGER constant. TOKEN also allows octal integers. Any field beginning with the character '"' is assumed to be an octal integer. 5. TYPFLT - token is a valid FORTRAN REAL constant. 6. TYPNAM - token begins with an alphabetic character and is followed by an arbitrary number of alphanumeric characters. 7. TYPSPC - token is a special character, i.e., NXTCHR does not begin a character string that is any of the above types of token. SYNTAX ANALYSIS Page 3-4 3.3 Syntax Error The name SYNERR means Syntax Error. The SYNERR subroutine first displays the current input LINE. It then replaces the previous token by question marks, and redisplays the line. CHAPTER 4 CHARACTER STRING MANIPULATION ROUTINES 4.1 Introduction Because Fortran does not provide the ability to manipulate character strings, this library contains a number of subroutines that process character strings. A single character is a LOGICAL*1 variable. A character string is a LOGICAL*1 array that is terminated by a zero byte. If an argument of the form 'string' is passed to a subroutine, Fortran-IV, Fortran-IV-Plus, and Fortran-77 append a null byte to the character string. Thus constant strings can be given as arguments to subroutines. It is the programmer's responsibility to ensure that a string does not overflow the array in which it is stored, and that all strings and characters are declared correctly. If you are using Fortran-77, the character string must still be declared as LOGICAL*1, not CHARACTER. CHARACTER variables may not be passed to any subroutines described in this manual. 4.2 String Length Syntax: LENSTR(STR,LEN) The LENSTR subroutine determines the length of a specified character string. LEN is set equal to the length of the string STR. LENSTR looks for the first null (zero byte). The call CALL LENSTR('EXAMPLE',LEN) will set LEN equal to 7. 4.3 Insert Character Syntax: ICHR(STR,IND,CHR) CHARACTER STRING MANIPULATION ROUTINES Page 4-2 The ICHR subroutine inserts a specified character before the indicated character of the specified character string. CHR is inserted before the INDth character of STR. If IND > LENGTH (STR), then CHR is concatenated to the end of STR. If STR is initially "TST", then after CALL ICHR(STR,2,'E') STR will have the value "TEST". 4.4 Concatenate Characters Syntax: CCCHR(STR,CHR) The CCCHR subroutine is used to concatenate a specified character onto the end of a specified character string. CHR is concatenated onto the end of STR. If STR is initially "TEST", then after CALL CCCHR(STR,'1') STR will have the value "TEST1". 4.5 Concatenate String Syntax: CCSTR(STR1,STR2) The CCSTR subroutine is used to concatenate a specified character string onto another character string. STR2 is concatenated onto the end of STR1. If STR is initially "NEW" then after CALL CCSTR(STR,' TEST') STR will have the value "NEW TEST". 4.6 Get Substring Syntax: GSTR(STR1,BEG,END,STR2) The GSTR subroutine gets the substring beginning and ending with the specified characters of the specified string. STR2 is set equal to the substring of STR1 whose first character is BEG and whose last character is END. No check is made to see if BEG and END are within STR1. After the call, CALL GSTR('ABCDEF',3,4,STR) STR will have the value 'CD'. CHARACTER STRING MANIPULATION ROUTINES Page 4-3 4.7 Delete Substring Syntax: DSTR(STR,BEG,END) The DSTR subroutine deletes a substring beginning and ending with the specified characters of the specified string. The substring of STR from BEG to END is deleted. For example, if the string is "ABCDE" and the call is CALL DSTR(STR,2,3) then STR will have the value "ADE". 4.8 Insert String Syntax: ISTR(STR,IND,STR2) Subroutine ISTR inserts a specified character string before the indicated characters of another specified character string. It inserts STR2 into STR1 before the INDth character of STR1. If IND > LENGTH(STR), then STR2 is concatenated to the end of STR1. If STR is initially "MARTIN KRAIMER", then after CALL ISTR(STR,8,'R. ') STR will have the value "MARTIN R. KRAIMER". 4.9 Move String Syntax: MSTR(STR1,STR2) The MSTR subroutine replaces one specified character string with another specified string. It moves STR1 to STR2. After a call to MSTR, STR2 will have exactly the same value as STR1. 4.10 Blank Removal Syntax: RLBS(STR) and RTBS(STR) The RLBS subroutine removes all leading blanks from the specified string, STR, while the RTBS subroutine removes all trailing blanks from the specified string, STR. CHARACTER STRING MANIPULATION ROUTINES Page 4-4 4.11 Get Index of Character Syntax: GICHR(STR,CHR,IND) The GICHR subroutine is used to determine the position or index of the indicated character within the specified string. It gets the index of CHR within STR. STR is searched for the first character equal to CHR. IND is set equal to the location within STR. If the character does not appear within STR, IND is set equal to zero. After the statement CALL GICHR('12/25/41','/',IND) IND will have the value 3. 4.12 Compare Strings Syntax: CMPSTR(STR1,STR2,IRES) The CMPSTR subroutine compares two strings and indicates whether they match or not. IRES is set equal to (-1,0,1) if STR1 is (<,=,>) STR2. The comparison is first on the collating sequence and then on the lengths of the strings. Examples: CMPSTR('ABCD','ABCD',IRES) IRES=0 CMPSTR('ABCD','ABCF',IRES) IRES=-1 CMPSTR('ABDD','ABCD',IRES) IRES=+1 CMPSTR('ABC','ABCD',IRES) IRES=-1 4.13 Convert String to Integer Syntax: CSTI(STR,IVAL) The CSTI subroutine converts an integer character string to an integer value. It converts STR to an INTEGER value and stores it in IVAL. Note that STR must represent a valid integer. After the call, CALL CSTI('123',IVAL) IVAL will be equal to 123. IVAL must be an INTEGER*2 variable. CHARACTER STRING MANIPULATION ROUTINES Page 4-5 4.14 Convert String to Octal Syntax: CSTO(STR,IVAL) The CSTO subroutine convert an octal integer character string to an octal integer. It converts STR to an OCTAL integer and stores it in IVAL. Note that STR must represent a valid octal integer. After the call, CALL CSTO('177777',IVAL) IVAL will be equal to -1. IVAL must be an INTEGER*2 variable. 4.15 Convert String to Real Number Syntax: CSTR(STR,RVAL) The CSTR subroutine converts a floating-point character string to a real number. It converts STR to a REAL value and stores it in RVAL. STR must represent a floating point number in standard fortran format. After the call, CALL CSTR('1.0E-01',RVAL) RVAL will have the value 0.1. 4.16 Convert Integer to String Syntax: CITS(STR,IVAL) The CITS subroutine converts an integer value to a character string. It converts the INTEGER IVAL to a character string and stores it in STR. After the call, CALL CITS(STR,652) STR will have the value 652. 4.17 Convert Real Number to String Syntax: CRTS(STR,RVAL) The CRTS subroutine converts a real number to a character string. It converts the REAL RVAL to a character string and stores it in STR. After the call, CHARACTER STRING MANIPULATION ROUTINES Page 4-6 CALL CRTS(STR,123.5) STR will have the value 123.5. CHAPTER 5 COMMAND PROCESSORS This chapter briefly discusses programs designed as command processors. A command processor is a program that accepts lines of the form cmd parm1 parm2 ... where each input line consists of a command and an arbitrary number of parameters. The command processor is expected to execute each command and then prompt for the next command. The next two sections describe subroutines that make it somewhat easier to write command processors. The last section of this chapter describes a simple command processor. 5.1 Get Next Command Line Syntax: GNCL(CMDLST,COMCP,CMDNUM) GNCL means "Get Next Command Line". CMDLST is a character string containing the list of commands accepted by the caller. Each command in the list is separated by a blank. COMCP is the name of a subroutine that GNCL calls to look for additional commands. CMDNUM is set equal to the index in CMD of the command found by GNCL. For example, the statement CALL GNCL('DATE TIME',COMCP,CMDNUM) states that the caller is willing to process two commands: DATE and TIME. It also gives the name of another routine, COMCP that is willing to process additional commands. GNCL calls PROMPT to get the next input line. If CNTLZ is set, GNCL sets CMDNUM=-1 and returns. If a null line is detected, (i.e., the user enters only the return key), GNCL sets CMDNUM=0 and returns. If neither of these conditions are true, GNCL calls TOKEN. It compares the token with the commands in CMDLST. If a match is found, GNCL sets CMDNUM equal to the position of the command in CMDLST and returns. In the above example if PROMPT returns LINE as COMMAND PROCESSORS Page 5-2 TIME 10:30:00 GNCL sets CMDNUM=2. Note that the next call to TOKEN returns the next token after the command name. If GNCL does not find the command in CMDLST, it calls COMCP with the statement CALL COMCP(FOUND) When COMCP is called, STRVAL contains the command to be processed. If COMCP sets FOUND true, GNCL begins again by calling PROMPT. If COMCP does not set FOUND true, GNCL calls SYNERR and tells the operator that this is an illegal command. It then begins again by calling PROMPT. It should now be clear that GNCL never returns to the caller until it finds a command the caller is willing to process or until a null line or end-of-file is detected. The calling program should clean up and exit if an end-of-file is detected. It can do whatever the programmer wants if a null line is detected. COMCP is useful if multiple command processors accept a common set of commands. For example if multiple programs are processing the same set of data files, a subroutine can be written to accept commands that manipulate the data files. Each program lets this subroutine process the data file commands, and only processes additional commands. 5.2 Get Next Parameter Syntax: GNP(PMTSTR,TYPE) GNP means Get Next Parameter. This subroutine calls TOKEN to get the next parameter from the current input line. If the token has TOKTYP=TYPE then GNP returns. If TOKTYP is not equal to TYPE then GNP does the following: If TOKTYP is not equal to TYPEOL, GNP calls SYNERR and prints an error message. In either case GNP calls PROMPT with PMTSTR as an argument. It then calls TOKEN and proceeds as above, i.e. it will not return until the operator returns a parameter of the appropriate type. COMMAND PROCESSORS Page 5-3 For example assume that a program is processing a command of the form: DATE yy mm dd Where yy, mm, dd are expected to be the year, month, and day given as integers. Assume that GNCL has already been called and the program branches to the following section of code which is expected to process the DATE command: CALL GNP('ENTER YEAR',TYPINT) YEAR=INTVAL CALL GNP('ENTER MONTH',TYPINT) MONTH=INTVAL CALL GNP('ENTER DAY',TYPINT) DAY=INTVAL 5.3 Example Command Processor The example command processor (Figure 1) accepts two commands: DATE and TIME. If either command is given without parameters, the currently defined date or time is listed. If parameters are given, the currently defined date or time is changed. The date is given in the form MM/DD/YY or in the form MM DD YY. The time is given in the form HH:MM:SS or in the form HH MM SS. Note that, because of the rules used by TOKEN, the parameters can be separated by commas instead of blanks. Thus the following are all legal commands: DATE TIME DATE 1/15/82 TIME 11:40:00 DATE 1,15,82 TIME 11 40 0 The DATE and TIME are initialized to be zero. COMCP is a dummy subroutine that does nothing. COMMAND PROCESSORS Page 5-4 FIGURE 1: SAMPLE COMMAND PROCESSOR PROGRAM COMAND C CLP DECLARATIONS FOR COMMAND LINE PROCESSING COMMON/CLP/ 1 TYPNUL,TYPEOL,TYPEL,TYPINT,TYPFLT,TYPNAM,TYPSPC, 2 TLU,CLPEFN,CNTLZ,TRACE, 3 LINE,NXTCHR,TOKLEN,TOKTYP,INTVAL,FLTVAL,STRVAL,CHRVAL INTEGER*2 TYPNUL,TYPEOL,TYPEL,TYPINT,TYPFLT,TYPNAM,TYPSPC INTEGER*2 TLU,CLPEFN,NXTCHR,TOKLEN,TOKTYP,INTVAL LOGICAL*1 LINE(82),STRVAL(82),CHRVAL LOGICAL CNTLZ,TRACE REAL FLTVAL C LOCAL DECLARATIONS INTEGER*2 DATE(3),TIME(3) EXTERNAL DUMMY INTEGER*2 CMDNUM DATA DATE/3*0/,TIME/3*0/ C BEGIN 1000 CALL GNCL('DATE TIME',DUMMY,CMDNUM) IF(CMDNUM.EQ.-1)STOP IF(CMDNUM.EQ.0)GO TO 1000 GOTO(1100,1200)CMDNUM 1100 CALL TOKEN C IF NO PARAMETERS ARE GIVEN JUST PRINT DATE IF(TOKTYP.NE.TYPEOL)GO TO 1110 WRITE(TLU,110)DATE 110 FORMAT(1H ,'DATE: ',I2,'/',I2,'/',I2) GO TO 1000 1110 DO 1150 I=1,3 IF(TOKTYP.EQ.TYPINT)GO TO 1120 CALL SYNERR CALL PLINE('ILLEGAL PARAMETER') GO TO 1000 1120 DATE(I)=INTVAL CALL TOKEN IF(CHRVAL.EQ.'/')CALL TOKEN 1150 CONTINUE GO TO 1000 COMMAND PROCESSORS Page 5-5 Figure 1, Continued: SAMPLE COMMAND PROCESSOR PROGRAM 1200 CALL TOKEN C IF NO PARAMETERS ARE GIVEN JUST PRINT TIME IF(TOKTYP.NE.TYPEOL)GO TO 1210 WRITE(TLU,120)TIME 120 FORMAT(1H ,'TIME: ',I2,':',I2,':',I2) GO TO 1000 1210 DO 1250 I=1,3 IF(TOKTYP.EQ.TYPINT)GO TO 1220 CALL SYNERR CALL PLINE('ILLEGAL PARAMETER') GO TO 1000 1220 TIME(I)=INTVAL CALL TOKEN IF(CHRVAL.EQ.':')CALL TOKEN 1250 CONTINUE GO TO 1000 END SUBROUTINE DUMMY(FOUND) LOGICAL FOUND C THIS ROUTINE DOES NOTHING END CHAPTER 6 MENU PROCESSORS In this manual, a "menu processor" means a program that prompts the operator for all input. It is particularly useful for novice operators or for programs that are used infrequently. Because the operator is prompted for all input, he does not have to remember any commands. The example given below performs the same functions as the command processor example given in Chapter 5, but it is written as a menu processor rather than as a command processor. When the program is started, it prompts the operator as follows: CMD>1=SET DATE,2=PRINT DATE,3=SET TIME,4=PRINT TIME? If the operator enters a CNTL/Z, the program terminates. If the operator enters a null line, he is again prompted for a command. If the operator gives a parameter value that is not an integer between 1 and 4, he receives a message that he has entered an illegal parameter and is again prompted for a new command. If the operator enters the value 1, he is prompted: CMD>DATE(MM/DD/YY)? The program calls TOKEN to retrieve each parameter. If an illegal parameter is detected, SYNERR is called, an error message is printed, and the operator is prompted for a new command. The program listing (Figure 2) can be studied to see how the remaining commands are processed. MENU PROCESSORS Page 6-2 FIGURE 2: SAMPLE MENU PROCESSOR PROGRAM PROGRAM MENU C CLP DECLARATIONS FOR COMMAND LINE PROCESSING COMMON/CLP/ 1 TYPNUL,TYPEOL,TYPEL,TYPINT,TYPFLT,TYPNAM,TYPSPC, 2 TLU,CLPEFN,CNTLZ,TRACE, 3 LINE,NXTCHR,TOKLEN,TOKTYP,INTVAL,FLTVAL,STRVAL,CHRVAL INTEGER*2 TYPNUL,TYPEOL,TYPEL,TYPINT,TYPFLT,TYPNAM,TYPSPC INTEGER*2 TLU,CLPEFN,NXTCHR,TOKLEN,TOKTYP,INTVAL LOGICAL*1 LINE(82),STRVAL(82),CHRVAL LOGICAL CNTLZ,TRACE REAL FLTVAL C LOCAL DECLARATIONS INTEGER*2 DATE(3),TIME(3) DATA DATE/3*0/,TIME/3*0/ C BEGIN 1000 CALL PROMPT('1=SET DATE,2=PRINT DATE,3=SET TIME,4=PRINT TIME') CALL TOKEN IF(CNTLZ)STOP IF(TOKTYP.EQ.TYPEL)GO TO 1000 IF(INTVAL.GE.1.AND.INTVAL.LE.4)GO TO 1010 CALL PLINE('ILLEGAL COMMAND. MUST BE >=1 AND <=4') GO TO 1000 1010 GO TO(1100,1200,1300,1400)INTVAL 1100 CALL PROMPT('DATE(MM/DD/YY)') CALL TOKEN IF(TOKTYP.EQ.TYPEL)GO TO 1000 1110 DO 1150 I=1,3 IF(TOKTYP.EQ.TYPINT)GO TO 1120 CALL SYNERR CALL PLINE('ILLEGAL PARAMETER') GO TO 1100 1120 DATE(I)=INTVAL CALL TOKEN IF(CHRVAL.EQ.'/')CALL TOKEN 1150 CONTINUE GO TO 1000 1200 WRITE(TLU,110)DATE 110 FORMAT(1H ,'DATE: ',I2,'/',I2,'/',I2) GO TO 1000 MENU PROCESSORS Page 6-3 Figure 2, Continued: SAMPLE MENU PROCESSOR PROGRAM 1300 CALL PROMPT('TIME(HH:MM:SS)') CALL TOKEN IF(TOKTYP.EQ.TYPEL)GO TO 1000 1310 DO 1350 I=1,3 IF(TOKTYP.EQ.TYPINT)GO TO 1320 CALL SYNERR CALL PLINE('ILLEGAL PARAMETER') GO TO 1300 1320 TIME(I)=INTVAL CALL TOKEN IF(CHRVAL.EQ.':')CALL TOKEN 1350 CONTINUE GO TO 1000 1400 WRITE(TLU,130)TIME 130 FORMAT(1H ,'TIME: ',I2,':',I2,':',I2) GO TO 1000 END CHAPTER 7 OPERATIONAL PROCEDURES To use the routines described in this manual, the programmer must include the CLP common definitions with his Fortran source program and must give the task builder a library containing the routines. If Fortran-IV-Plus or Fortran-77 are being used, the Fortran INCLUDE statement can be used to include the definitions for CLP. If Fortran-IV is being used, the programmer must use a standard editor to include the definitions. The definitions are in the file 'CLP.COM'. The following is the indirect command file used to task-build the COMAND example given previously. It can be used as a model for other programs. LIB is the library containing the routines described in this chapter. F4POTS is the Fortran-IV-Plus library. Note that logical units 1, 2, and 3 are used. The RSX-11M command line routines use unit 1. This can be changed by changing the macro call GCMLB$ in GCML. Logical unit 2 is the terminal logical unit. Logical unit 3 is used by the LEARN command. The terminal logical unit is defined in a DATA statement in PROMPT. The LEARN logical unit is also defined by a statement in PROMPT. COMAND/CP/FP=COMAND,LIB/LB LB:[1,1]F4POTS/LB / ASG=TI:1:2,SY:3 RESLIB=LB:[1,1]FCSRES/RO:7 TASK=...CMD // All files needed to use the routines described in this manual are stored under a single UIC. Three files CLP.COM, CLP.INI, and CLP.DEF contain the Fortran definitions, initialization statements, and comment statements for common block CLP. Command files are available to generate an object module library. File CREATEFOR.CMD will create a library for Fortran-IV and CREATEF4P.CMD will create a library for Fortran-IV-Plus. APPENDIX A INCLUDE LIBRARY C CLP DECLARATIONS FOR COMMAND LINE PROCESSING COMMON/CLP/ 1 TYPNUL,TYPEOL,TYPEL,TYPINT,TYPFLT,TYPNAM,TYPSPC, 2 TLU,CLPEFN,CNTLZ,TRACE, 3 LINE,NXTCHR,TOKLEN,TOKTYP,INTVAL,FLTVAL,STRVAL,CHRVAL,USICHR INTEGER*2 TYPNUL,TYPEOL,TYPEL,TYPINT,TYPFLT,TYPNAM,TYPSPC INTEGER*2 TLU,CLPEFN,NXTCHR,TOKLEN,TOKTYP,INTVAL LOGICAL*1 LINE(82),STRVAL(82),CHRVAL,USICHR LOGICAL CNTLZ,TRACE REAL FLTVAL C INITIAL VALUES FOR CLP COMMON DATA TYPNUL/0/,TYPEOL/1/,TYPEL/2/,TYPINT/3/ DATA TYPFLT/4/,TYPNAM/5/,TYPSPC/6/ DATA TLU/2/,CLPEFN/1/,CNTLZ/.FALSE./,TRACE/.FALSE./ DATA LINE/82*0/,NXTCHR/1/,TOKLEN/0/,TOKTYP/0/ DATA INTVAL/0/,FLTVAL/0.0/,STRVAL/82*0/,CHRVAL/0/ C DEFINITION OF VARIABLES IN CLPCOM C TYPNUL - NULL PARAMETER. I.E. ,, C TYPEOL - END OF LINE C TYPEL - EMPTY LINE C TYPINT - INTEGER C TYPFLT - FLOATING POINT NUMBER C TYPNAM - NAME. VALUE IS STORED IN STRVAL C TYPSPC - SPECIAL TYPE. VALUE IS STORED IN CHRVAL C TLU - TERMINAL LOGICAL UNIT C CLPEFN - EVENT FLAG USABLE BY ANYONE WHO WAITS IMMEDIATELY C CNTLZ - HAS USER GIVEN CNTL/Z C TRACE - TRACE LINES FROM COMMAND FILE? C LINE - CURRENT COMMAND LINE C NXTCHR - NEXT CHARACTER OF LINE FOR TOKEN C TOKLEN - LENGTH OF PREVIOUS TOKEN C TOKTYP - TYPE OF PREVIOUS TOKEN C INTVAL - INTEGER VALUE OF PREVIOUS TOKEN C FLTVAL - FLOATING POINT VALUE OF PREVIOUS TOKEN C STRVAL - STRING VALUE OF PREVIOUS TOKEN C CHRVAL - CHARACTER VALUE OF PREVIOUS TOKEN C USICHR - UNSOLICITED INTERRUPT CHARACTER APPENDIX B SUMMARY OF LIBRARY SUBROUTINES Subroutine Name Operation Performed __________ ____ _________ _________ TERMINAL I/O PROMPT(STR) Prompts and accepts input. PLINE(STR) Sends STR to terminal. USIBEG Begin Unsolicited Terminal Input USIEND End Unsolicited Terminal Input SYNTAX ANALYSIS TOKEN Gets next token. SYNERR Reports syntax error. CHARACTER STRING SUBROUTINES LENSTR(STR,LEN) Sets LEN equal to length of STR. ICHR(STR,IND,CHR) Inserts CHR before IND'th char of STR. CCCHR(STR,CHR) Concatenates CHR onto end of STR. CCSTR(STR1,STR2) Concatenates STR2 onto end of STR1. GSTR(STR1,BEG,END,STR2) Gets substring delimited by BEG and END. DSTR(STR,BEG,END) Deletes substring delimited by BEG and END. ISTR(STR1,IND,STR2) Inserts STR2 before IND'th CHR of STR1. MSTR(STR1,STR2) Moves STR1 to STR2. RLBS(STR) Removes leading blanks from STR. RTBS(STR) Removes trailing blanks from STR. GICHR(STR,CHR,IND) Gets index of CHR within STR. CMPSTR(STR1,STR2,IRES) Sets IRES=(-1,0,1) IF STR1 (<,=,>) STR2 CSTI(STR,IVAL) Converts string to integer value. CSTO(STR,IVAL) Converts string to octal value. CSTR(STR,RVAL) Converts string to real value. CITS(STR,IVAL) Converts integer to string. CRTS(STR,RVAL) Converts real value to string. COMMAND PROCESSOR GNCL(CMDLST, Gets next command line. COMCP,CMDNUM) GNP(PMTSTR,TYPE) Get Next Parameter SUMMARY OF LIBRARY SUBROUTINES Page B-2 Table of Contents 1.0 INTRODUCTION . . . . . . . . . . . . . . 1-1 2.0 TERMINAL I/O SUBROUTINES . . . . . . . . 2-1 2.1 Use of PROMPT Subroutine . . . . . . . . 2-1 2.1.1 Using Indirect Command Files . . . . . . 2-2 2.1.2 Using TRACE, LEARN, and HELP Commands . 2-3 2.1.3 Using Imbedded Prompt Strings . . . . . 2-3 2.2 Processing Unsolicited Terminal Input . 2-4 2.3 Summary of Subroutine Algorithms . . . . 2-5 2.3.1 Prompt . . . . . . . . . . . . . . . . . 2-5 2.3.2 Put Line . . . . . . . . . . . . . . . . 2-5 2.3.3 Get Command Line . . . . . . . . . . . . 2-5 2.3.4 Unsolicited Terminal Input . . . . . . . 2-5 3.0 SYNTAX ANALYSIS . . . . . . . . . . . . 3-1 3.1 Introduction . . . . . . . . . . . . . . 3-1 3.2 Token . . . . . . . . . . . . . . . . . 3-1 3.3 Syntax Error . . . . . . . . . . . . . . 3-4 4.0 CHARACTER STRING MANIPULATION ROUTINES . 4-1 4.1 Introduction . . . . . . . . . . . . . . 4-1 4.2 String Length . . . . . . . . . . . . . 4-1 4.3 Insert Character . . . . . . . . . . . . 4-1 4.4 Concatenate Characters . . . . . . . . . 4-2 4.5 Concatenate String . . . . . . . . . . . 4-2 4.6 Get Substring . . . . . . . . . . . . . 4-2 4.7 Delete Substring . . . . . . . . . . . . 4-3 4.8 Insert String . . . . . . . . . . . . . 4-3 4.9 Move String . . . . . . . . . . . . . . 4-3 4.10 Blank Removal . . . . . . . . . . . . . 4-3 4.11 Get Index of Character . . . . . . . . . 4-4 4.12 Compare Strings . . . . . . . . . . . . 4-4 4.13 Convert String to Integer . . . . . . . 4-4 4.14 Convert String to Octal . . . . . . . . 4-5 4.15 Convert String to Real Number . . . . . 4-5 4.16 Convert Integer to String . . . . . . . 4-5 4.17 Convert Real Number to String . . . . . 4-5 5.0 COMMAND PROCESSORS . . . . . . . . . . . 5-1 5.1 Get Next Command Line . . . . . . . . . 5-1 5.2 Get Next Parameter . . . . . . . . . . . 5-2 5.3 Example Command Processor . . . . . . . 5-3 6.0 MENU PROCESSORS . . . . . . . . . . . . 6-1 7.0 OPERATIONAL PROCEDURES . . . . . . . . . 7-1 A.0 INCLUDE LIBRARY . . . . . . . . . . . . A-1 B.0 SUMMARY OF LIBRARY SUBROUTINES . . . . . B-1