Parsing TCL Commands (TB#32) (Functions/Subroutines/Programs)
Created at 12 AUG 1996 03:27PM
Parsing TCL Commands
Many programs are written to scan @SENTENCE and extract program parameters from the TCL command line. In order to do this, programs must not only parse each word of the command line, but must also account for the extra spaces a user may embed in a command.
A system subroutine already available accomplishes this task. This routine is RTP29.
The system subroutine RTP29 substitutes a record mark (@RM) for all delimiter spaces in a string. Quoted spaces (those that are enclosed in matching sets of single or double quotes) are left intact.
As a system subroutine, RTP29 can also set various option flags. However, these option flags cannot be read by non-system programs, and are therefore unusable to application developers.
RTP29 Syntax
The syntax for RTP29 is:
RTP29( COMMAND, ARRAY, OPTIONS )
where:
COMMAND the string to be converted
ARRAY the string after it has been converted to an array
OPTIONS a flag. If true, RPT29 will parse option flags that are between parentheses and set system flags accordingly. When doing so, RTP29 will clear the option flags from the input string.
Because application programs cannot read the system flags set in this way, developers should pass this parameter as false in order to preserve the command-line option flags.
A sample program illustrating a possible means of using RTP29 appears in Figure 1.
Parsing Options
Because non-system programs cannot use RTP29's ability to set option flags, an alternative strategy is necessary. One method is to parse the TCL command looking for parentheses, extract the text between the parentheses, and then remove the parenthetical element from the TCL command.
Once the element has been removed, it can be scanned for particular options. The interpretation of the options between parentheses is program-specific. A typical method is to read each option letter and pass through CASE logic to determine what switches to set.
Figure 2 amplifies the program in Figure 1 by including logic to parse out and set options passed in parentheses.
Figure 1
DECLARE SUBROUTINE RTP29, MSG
COMMAND = @SENTENCE
FLAG = 0 ; * necessary to retain options
CALL RTP29( COMMAND, ARRAY, FLAG )
CONVERT @RM TO @FM IN ARRAY
* makes spaces visible
CONVERT ' 'TO '.' IN ARRAY
* display array as returned by RTP29
ELEMENT.CNT = COUNT( ARRAY, @FM ) ( ARRAY NE )
FOR CTR = 1 TO ELEMENT.CNT
NEXT.ELEMENT = ARRAY< CTR >
TEXT = 'Element #':CTR:' of the command is:'
TEXT←1> = NEXT.ELEMENT
MSG(TEXT,
,,
)
NEXT CTR
STOP
Figure 2
DECLARE SUBROUTINE RTP29, MSG
COMMAND = @SENTENCE
* initialize options used in this program
S.OPTION = 0; P.OPTION = 0; T.OPTION = 0
* parse out options passed between parentheses look for opening parenthesis
OPTIONS = INDEX( COMMAND,'(', 1)
IF OPTIONS THEN
* look for closing parenthesis
OPTIONS = COMMAND[ OPTIONS+1,')' ]
* clear options out of command
OPTIONS.LEN = COL2() - COL1()+1
COMMAND[ COL1(), OPTIONS.LEN ] = ''
* examine options, set program-specific flags
OPTIONS.CNT = LEN( OPTIONS )
FOR CTR = 1 TO OPTIONS.CNT
NEXT.OPTION = OPTIONS[ CTR, 1 ]
BEGIN CASE
CASE NEXT.OPTION = 'P'
P.OPTION = 1
PRINTER ON
CASE NEXT.OPTION = 'S'
S.OPTION = 1
CASE NEXT.OPTION = 'T'
T.OPTION = 1
PRINTER OFF
CASE 1
END CASE
NEXT CTR
END ; * if options
* in this instance, FLAG can be set either way, since the options have
* already been scanned
FLAG = 0
COMMAND = TRIMB( COMMAND ) ; * clear space left by options
CALL RTP29( COMMAND, ARRAY, FLAG )
(etc.)