| United States-English |
|
|
|
![]() |
HP OpenVMS Systems Documentation |
DECset
|
| Previous | Contents | Index |
LSE provides a mechanism for defining your own packages. The package
facility includes two DECTPU sets of procedures to help you write your
own packages.
C.1 DECTPU Procedures for the Package Facility
The DECTPU procedures generate the appropriate DEFINE TOKEN and DEFINE PLACEHOLDER commands for each routine or parameter. The DECTPU procedures, indicated by the /ROUTINE_EXPAND qualifier, generate a token definition for the routine name. The DECTPU procedures, indicated by the /PARAMETER_EXPAND qualifier, generate one or more placeholder definitions for each parameter name.
LSE comes with two sets of predefined DECTPU procedures that you can use to perform these expansions. For each language associated with the package, there must be a ROUTINE_EXPAND and PARAMETER_EXPAND procedure. You can specify these procedures with the /ROUTINE_EXPAND and /PARAMETER_EXPAND qualifiers. The value that you specify for these qualifiers in the DEFINE PACKAGE command must be a prefix shared by all the corresponding procedures. LSE determines the actual procedure name by concatenating the prefix value and the appropriate language name.
The procedures supplied with LSE are as follows:
You use these routines by specifying the following:
/ROUTINE_EXPAND = LSE$PKG_EXPAND_ROUT_ /PARAMETER_EXPAND = LSE$PKG_EXPAND_PARM_ |
If you want to write your own DECTPU procedures for these purposes, they must conform to the following restrictions:
PROCEDURE my_routine_expand_somelanguage
LOCAL command_string, {other tpu local variables}...;
. . .
command_string := 'DEFINE TOKEN '
+ routine_name
+ '/LANGUAGE = somelanguage '
+ <any other qualifiers for the DEFINE TOKEN command>;
LSE$DO_COMMAND (command_string) ;
< tpu code to generate the body of the token, using LSE$DO_COMMAND>
LSE$DO_COMMAND ('END DEFINE');
ENDPROCEDURE;
|
All the information included in the DEFINE ROUTINE command is
passed to your DECTPU routine by means of the DECTPU global variables.
The following global variables are defined:
| Variable | Description |
|---|---|
| LSE$PKG_ROUT_NAME | Contains the name of the routine being defined, enclosed in quotes ("). |
| LSE$PKG_ROUT_LANG | Contains the name of the language. |
| LSE$PKG_ROUT_DESC | Contains the value of the /DESCRIPTION parameter. |
| LSE$PKG_ROUT_TOP | Contains the value of the /TOPIC parameter. |
| LSE$PKG_ROUT_PACK | Contains the package name. |
| LSE$PKG_ROUT_PARM | Contains the list of parameters associated with the routine being defined. Each parameter is enclosed in quotes and separated from the next by a carriage return, line feed pair; that is, the TPU string ASCII(13) + ASCII(10). |
| LSE$PKG_ROUT_OPT | Contains a list of flags, in one-to-one correspondence to the list of parameters. Each flag can be either O, indicating that the parameter is optional, or R, indicating that the parameter is required. Each flag is separated from the next by a single-space character. |
| LSE$PKG_ROUT_MECH |
Contains a list of flags, in one-to-one correspondence to the list of
parameters. Each flag can have one of the following values:
Each flag is separated from the next by a single-space character. |
PROCEDURE my_parameter_expand_somelanguage
LOCAL command_string, {other tpu local variables}...;
. . .
command_string := 'DEFINE PLACEHOLDER '
+ routine_name
+ '/LANGUAGE = somelanguage '
+ '/TYPE = TERMINAL/SEPARATOR = ","'
+ {other qualifiers for the DEFINE PLACEHOLDER command};
LSE$DO_COMMAND (command_string) ;
. . .
ENDPROCEDURE;
|
| Variable | Description |
|---|---|
| LSE$PKG_PARA_NAME | Contains the name of the parameter to be defined. |
| LSE$PKG_PARA_LANG | Contains the name of the language. |
This section presents the TPU expansion procedures for Pascal and some of the support routines. The first TPU procedure, LSE$PKG_EXPAND_ROUT_PASCAL, defines a token for a package routine. It calls other TPU procedures that you can use as is or redefine according to your needs.
The second procedure, LSE$PKG_EXPAND_PARM_PASCAL, defines two placeholders for each parameter. Because the Pascal system-service routines are in a keyword format (for example, %[p1 := %{p1}%]%), a placeholder must be defined for p1 and p1 := %{p1}%. The first placeholder is defined in the procedure LSE$PKG_DEFINE_PARAMETER, and the second in LSE$PKG_EXPAND_PARAM_PASCAL.
The following called procedures are also listed:
Note that the TPU built-in procedure, change_case, is called to force the case of expansions. You can modify the expansion routines to use CHANGE_CASE to follow any case convention you want.
PROCEDURE lse$pkg_expand_rout_pascal
!++
! FUNCTIONAL DESCRIPTION:
!
! This routine generates a Pascal token definition from a parameter
! definition using keyword syntax.
!
! FORMAL PARAMETERS:
!
! None
!
! IMPLICIT INPUTS:
!
! LSE$PKG_ROUT_NAME
! The name of the routine to be defined.
!
! LSE$PKG_ROUT_PARM
! The list of parameters of the routine separated by spaces.
!
! LSE$PKG_ROUT_OPT
! A list of flags in one-to-one correspondence with the list of
! parameters. Each flag can be either O, indicating optional, or
! R, indicating required. Each flag is separated from the next by a
! space.
!
! IMPLICIT OUTPUTS:
!
! None
!
! ROUTINE VALUE:
!
! None
!
! SIDE EFFECTS:
!
! A token definition is issued.
!--
LOCAL
proc_name,
command_string,
cur_param,
cur_option,
param_name,
keyword_param,
mech;
! Start the DEFINE TOKEN command.
lse$pkg_define_token;
! Remove quotes from procedure name.
proc_name := SUBSTR(LSE$PKG_ROUT_NAME, 2, LENGTH(LSE$PKG_ROUT_NAME)-2);
! Format the call with the procedure name in lowercase.
command_string := '"' + proc_name;
CHANGE_CASE(command_string,LOWER);
IF LSE$PKG_ROUT_PARM = '' THEN
! The call consists of just the procedure name
command_string := command_string + '"';
LSE$DO_COMMAND(command_string);
ELSE
! The call has parameters
! Form the first line of the call.
! First line is just the procedure name and open parenthesis.
command_string := command_string + ' (';
LSE$DO_COMMAND(command_string);
! Move a required parameter to the beginning of the list.
! This avoids a problem in erasing a comma after the first
! parameter if it is optional.
lse$pkg_reorder_params (LSE$PKG_ROUT_PARM, LSE$PKG_ROUT_OPT);
! Loop for each parameter.
LOOP
EXITIF lse$pkg_get_param (cur_param,
cur_option,
LSE$PKG_ROUT_PARM,
LSE$PKG_ROUT_OPT) = 0;
! Remove passing mechanism .x suffix (x = v, d, or r).
keyword_param := lse$pkg_remove_mech (cur_param, mech);
! Modify parameter names that conflict with Pascal keywords.
IF keyword_param = "TYPE"
THEN
keyword_param := keyword_param + '_';
ENDIF;
lse$pkg_pad_name (keyword_param, param_name);
! Form the template line for the parameter.
command_string := '"' + ASCII(9);
IF cur_option = "O"
THEN
! optional parameter
command_string := command_string
+ '%[' + param_name + ' := %{' + cur_param + '}%]%'
ELSE
! required parameter
command_string := command_string
+ param_name + ' := %{' + cur_param + '}%'
ENDIF;
IF LSE$PKG_ROUT_PARM = '' THEN ! No more parameters
! Complete the call statement.
command_string := command_string + ')';
ELSE
! Add a separator after the parameter.
command_string := command_string + ',';
ENDIF ;
! Make the line lowercase.
CHANGE_CASE (command_string,LOWER);
! Add the line to the token definition.
LSE$DO_COMMAND (command_string);
ENDLOOP;
ENDIF; ! parameter string is/isn't empty
! End the DEFINE TOKEN command
LSE$DO_COMMAND ("end define") ;
ENDPROCEDURE
|
PROCEDURE lse$pkg_expand_parm_pascal
!++
! FUNCTIONAL DESCRIPTION:
!
! This routine generates Pascal placeholder definitions from a parameter
! definition for keyword syntax.
!
! FORMAL PARAMETERS:
!
! None
!
! IMPLICIT INPUTS:
!
! LSE$PKG_PARA_NAME
! The name of the placeholder to define.
!
! IMPLICIT OUTPUTS:
!
! None
!
! ROUTINE VALUE:
!
! None
!
! SIDE EFFECTS:
!
! Two placeholder definitions are issued.
!--
LOCAL
command_string,
name_noquote,
padded_key,
keyword_name,
mech;
! Define a placeholder for the parameter.
lse$pkg_define_parameter('');
! Define a placeholder of the form "name := %{name}%".
! This is done in case the parameter is optional.
! Strip the quotes off the name
name_noquote := SUBSTR( LSE$PKG_PARA_NAME,
2,
LENGTH(LSE$PKG_PARA_NAME) - 2) ;
! Remove passing mechanism .x suffix (x = v, d, or r).
keyword_name := lse$pkg_remove_mech (name_noquote, mech);
! Modify parameter names that conflict with Pascal keywords
IF keyword_name = 'TYPE'
THEN
keyword_name := keyword_name + '_';
ENDIF;
lse$pkg_pad_name (keyword_name, padded_key) ;
! Do the DEFINE PLACEHOLDER command.
command_string :=
'define placeholder /language=pascal /separator="," "' +
padded_key + ' := %{' + name_noquote + '}%"' ;
CHANGE_CASE (command_string, lower);
LSE$DO_COMMAND (command_string) ;
! Do the body.
command_string := '"' + padded_key + ' := %{' + name_noquote + '}%"' ;
CHANGE_CASE (command_string, LOWER);
LSE$DO_COMMAND (command_string) ;
! End the definition.
LSE$DO_COMMAND ('end define') ;
ENDPROCEDURE
|
PROCEDURE lse$pkg_pad_name (cur_param, p_keyword)
!++
! FUNCTIONAL DESCRIPTION:
!
! Pads a parameter name so that it is at least six characters long. This
! is for use by keyword-style routine calls, so that the intermediate
! assignment operations, which separate the keyword from the parameter value,
! line up properly.
!
! FORMAL PARAMETERS:
!
! cur_param
! The parameter name to be padded.
!
! p_keyword
! The result of padding the parameter name.
!
! IMPLICIT INPUTS:
!
! None
!
! IMPLICIT OUTPUTS:
!
! None
!
! ROUTINE VALUE:
!
! None
!
! SIDE EFFECTS:
!
! p_keyword is set as indicated above
!--
LOCAL
len, !* the length of cur_param
i ;
p_keyword := cur_param;
! Pad the p_keyword so it's six letters long.
! This tends to make the keyword calls to system services look
! better.
len := LENGTH (p_keyword) ;
IF len < 6 THEN
i := 0 ;
LOOP EXITIF i = 6 - len ;
p_keyword := p_keyword + " " ;
i := i + 1 ;
ENDLOOP ;
ENDIF ;
ENDPROCEDURE
|
PROCEDURE lse$pkg_define_token
!++
! FUNCTIONAL DESCRIPTION:
!
! This routine generates LSE DEFINE TOKEN commands for routines.
! It issues only the DEFINE TOKEN token-name, with qualifiers, and
! leaves the editor in a state ready to process the definition of
! the body of the token. This procedure is suitable for being
! called from any procedure that needs to define a token from a
! routine definition; the calling procedure is responsible for
! defining the body of the routine and issuing the closing END
! DEFINE command.
!
! FORMAL PARAMETERS:
!
! None
!
! IMPLICIT INPUTS:
!
! LSE$PKG_ROUT_NAME
! The name of the routine to be defined.
!
! LSE$PKG_ROUT_LANG
! The name of the language for which to define the routine.
!
! LSE$PKG_ROUT_DESC
! The description string for the routine.
!
! LSE$PKG_ROUT_TOP
! The topic string for the routine.
!
! IMPLICIT OUTPUTS:
!
! None
!
! ROUTINE VALUE:
!
! None
!
! SIDE EFFECTS:
!
! Begins a DEFINE TOKEN definition. The next calls to
! LSE$DO_COMMAND must complete the definition.
!
! MODIFICATION HISTORY:
!
!--
LOCAL
proc_name, ! name of routine being defined, with quotes removed
command_string; ! command string to send to LSE$DO_COMMAND
! Form DEFINE TOKEN command string
command_string :=
'define token ' + LSE$PKG_ROUT_NAME
+ ' /language = ' + LSE$PKG_ROUT_LANG
+ ' /description = "' + LSE$PKG_ROUT_DESC
+ '" /topic_string = "' + LSE$PKG_ROUT_TOP + '"';
! Execute the DEFINE TOKEN command
LSE$DO_COMMAND (command_string) ;
ENDPROCEDURE;
|
PROCEDURE lse$pkg_get_param (param, option, param_line, option_line)
!++
! FUNCTIONAL DESCRIPTION:
!
! Return the first parameter and option from the given parameter
! lists and option line, which removes them from the lists.
!
! FORMAL PARAMETERS:
!
! param
! On exit, this will be the first parameter from the param line.
!
! option
! On exit, this will be the first option field from the option line.
!
! param_line
! A list of parameters for a routine, as in LSE$PKG_ROUT_PARM. On exit,
! the first parameter from the list will have been removed.
!
! option_line
! A list of option flags for a routine's parameter list, as in
! LSE$PKG_ROUT_OPT. On exit, the first option from the list will have
! been removed.
!
! IMPLICIT INPUTS:
!
! None
!
! IMPLICIT OUTPUTS:
!
! None
!
! ROUTINE VALUE:
!
! 0 - if there were no more parameters
! 1 - if a parameter name is returned
!
! SIDE EFFECTS:
!
! param_line and option_line are changed as indicated above
!--
LOCAL
blank_idx ; ! ** location of blanks in parameter lines
! Locate a parameter in param_line.
blank_idx := INDEX (param_line, ASCII(13)+ASCII(10) );
! Return if no more parameters.
IF blank_idx <= 1 THEN
param_line := '' ;
RETURN (0) ;
ENDIF ;
! Get parameter, stripping off the outside set of quotes.
param := SUBSTR (param_line, 2, blank_idx - 3) ;
! Remove parameter from param_line.
param_line := SUBSTR (param_line, blank_idx + 2, LENGTH(param_line) ) ;
! Get option and remove from option_line.
option := SUBSTR (option_line, 1, 1) ;
option_line := SUBSTR (option_line, 3, LENGTH(option_line) ) ;
RETURN (1) ;
ENDPROCEDURE
|
PROCEDURE lse$pkg_define_parameter(qualifiers)
!++
! FUNCTIONAL DESCRIPTION:
!
! This procedure issues a standard DEFINE PARAMETER command for the parameter
! currently being expanded. This routine is suitable for being called from
! any procedure that needs to define a placeholder from a parameter. Note that
! unlike lse$pkg_define_token, this routine generates a complete placeholder
! definition.
!
! FORMAL PARAMETERS:
!
! qualifiers
! A string containing any additional qualifiers to be added to the
! placeholder definition. Most commonly, this will be either empty
! or just a separator definition (for example, '/SEPARATOR=","'). Note that
! the parameter must be a complete qualifier or sequence of qualifier,
! in legal LSE syntax. Furthermore, since this routine automatically
! adds a /type=terminal and a /language=lse$pkg_para_lang to the
! placeholder definitions, these two qualifiers may NOT be included in
! the qualifiers parameters.
!
!
! IMPLICIT INPUTS:
!
! LSE$PKG_PARA_NAME
! The name of the placeholder to define.
!
! LSE$PKG_PARA_LANG
! The language for which to define the placeholder.
!
! IMPLICIT OUTPUTS:
!
! None
!
! ROUTINE VALUE:
!
! None
!
! SIDE EFFECTS:
!
! A new placeholder is defined.
!--
LOCAL
command_string,
name_noquote,
mech;
! Form DEFINE PLACEHOLDER command string
command_string :=
'define placeholder ' + LSE$PKG_PARA_NAME +
' /type=terminal /language=' + LSE$PKG_PARA_LANG
+ qualifiers;
! Force to lowercase
CHANGE_CASE (command_string, LOWER);
! Execute the DEFINE PLACEHOLDER command
LSE$DO_COMMAND (command_string);
! Strip the quotes off the name
name_noquote := SUBSTR(LSE$PKG_PARA_NAME, 2, LENGTH(LSE$PKG_PARA_NAME) - 2);
! Remove passing mechanism .x suffix (x = v, d, or r).
name_noquote := lse$pkg_remove_mech (name_noquote, mech);
! Do the body line.
command_string := '"The actual data you want to pass to parameter ' +
name_noquote + '."';
LSE$DO_COMMAND (command_string);
! Do a body line for the passing mechanism.
IF mech = 'V' THEN
LSE$DO_COMMAND('"The parameter is passed by value."');
ELSE IF mech = 'R' THEN
LSE$DO_COMMAND('"The parameter is passed by reference."');
ELSE IF mech = 'D' THEN
LSE$DO_COMMAND('"The parameter is passed by descriptor."');
ENDIF; ENDIF; ENDIF;
! End the DEFINE PLACEHOLDER command
LSE$DO_COMMAND ("end define")
ENDPROCEDURE
|
PROCEDURE lse$pkg_remove_mech(param_name, mech_char)
!++
! FUNCTIONAL DESCRIPTION:
!
! This procedure removes a suffix from a parameter name of the form
! name.suffix. The suffix must be either v, d, or r and
! indicate that the parameter is passed by value, descriptor, or
! reference, respectively.
!
! FORMAL PARAMETERS:
!
! param_name
! The name of the parameter.
!
! mech_char
! Set to the suffix character removed from param_name (uppercase).
!
! IMPLICIT INPUTS:
!
! None
!
! IMPLICIT OUTPUTS:
!
! None
!
! ROUTINE VALUE:
!
! The parameter name without the .suffix.
!
! SIDE EFFECTS:
!
! None
!--
LOCAL
param_length,
mech_suffix,
mech_separator;
mech_char := '';
param_length := LENGTH (param_name) ;
IF param_length < 2 THEN RETURN (param_name) ENDIF;
! Get last character from param_name.
mech_suffix := SUBSTR(param_name, param_length, 1);
! Get second-to-last character from param_name.
mech_separator := SUBSTR(param_name, param_length - 1, 1);
CHANGE_CASE (mech_suffix, UPPER);
IF ((mech_suffix = 'V') OR (mech_suffix = 'D') OR (mech_suffix = 'R'))
AND (mech_separator = '.') THEN
mech_char := mech_suffix;
RETURN ( SUBSTR (param_name, 1, param_length - 2) ) ;
ENDIF;
RETURN (param_name);
ENDPROCEDURE
|
| Previous | Next | Contents | Index |
|
|||||||||||||||