Predefined Routines [ HP Pascal/iX Reference Manual ] MPE/iX 5.0 Documentation
HP Pascal/iX Reference Manual
Predefined Routines
The system programming extensions define the following additional
predefined procedures and functions.
Addressing and Pointers
Addr.
The predefined function addr allows the user to create references to
routines or data.
Usage
addr(variable)
addr(variable,offset)
addr(routine-name)
Parameters
variable A variable or reference parameter, or a component
of an unpacked structured variable or reference
parameter. You can take the address of a component
of a packed or crunched structure, if the component
begins on a byte-aligned boundary.
offset A signed integer expression.
routine-name The name of a procedure or function.
Description
The predefined function addr returns a pointer value that is the address
of the argument. The type of the pointer returned by addr is assignment
compatible with any pointer type. Addr returns a short or long pointer
depending on the context in which it is called, the context being the
type of the target variable of an assignment, the type of a formal
parameter, or the target type of a type coercion.
If the type coercion target type is not a pointer type, addr returns a
globalanypointer.
If an integer argument is supplied, the pointer returned is offset by the
integer number of bytes from the original variable whose address was
taken.
It is illegal to take the address of a formal value or READONLY
parameter.
It is illegal to take the address of a component of a PACKED or CRUNCHED
structure, if the component does not begin on a byte-aligned boundary.
If addr is called with the name of a procedure or function, the value
returned is a reference to that procedure or function. The function
result type is assignment compatible with a PROCEDURE or FUNCTION type
whose parameter list is congruent with the parameter list of the routine
passed to addr.
If the name passed to addr cannot be resolved, the value NIL is returned.
Example
$STANDARD_LEVEL 'HP_MODCAL', TYPE_COERCION 'CONVERSION'$
TYPE
p_to_p_type = ^ p_to_p_type;
VAR
p_to_p : p_to_p_type;
BEGIN
p_to_p := addr( p_to_p );
p_to_p := p_to_p_type( addr( p_to_p^, sizeof( p_to_p^ ) ) )^;
END
The first assignment points the pointer p_to_p to itself. The second
assignment takes the address of the data referenced by p_to_p (which is
itself), offset by the size of the data that p_to_p points to, treats the
value at that location as a pointer, and assigns the value pointed to by
that pointer back to p_to_p.
Addtopointer.
The predefined function addtopointer allows the user to perform address
arithmetic with pointers.
Usage
addtopointer(pointer, delta)
Parameters
pointer A pointer expression.
delta A signed integer expression whose range restriction
is implementation dependent.
Description
Addtopointer returns a pointer value that points delta bytes away from
where the argument pointer pointed. The type of the pointer returned by
addtopointer is the same as the type of the parameter pointer.
The results of an overflow are implementation dependent.
Example
TYPE
intptr = ^integer;
VAR
ptr1: intptr;
ptr2: intptr;
i: integer;
BEGIN
ptr2 := addtopointer (ptr1, i);
ptr1 := addtopointer (ptr1, sizeof(integer));
END
Buildpointer.
The predefined function buildpointer allows the user to construct pointer
values.
Usage
buildpointer(space,offset)
Parameters
space A space identifier whose range restriction and
semantics are implementation dependent.
offset A bit32 expression whose range restriction is
implementation dependent.
Description
buildpointer returns a pointer of type globalanyptr whose value is the
address offset bytes into space.
Example
CONST
Global_Known_Space = 4916;
VAR
Ptr1 : GlobalAnyPtr;
Ptr2 : GlobalAnyPtr;
SID : Integer;
Off : Integer;
BEGIN
Ptr1 := BuildPointer (Global_Known_Space, 0);
off := 4;
Ptr2 := BuildPointer (SID, Off);
END.
In the above example, the constant Global_Known_Space represents the
value of a known space.
The first use of buildpointer creates a pointer to the location with an
offset of zero in the space whose space id is Global_Known_Space.
The second use of buildpointer creates a pointer to the location four
bytes from the beginning of the space whose space has been assigned to
the variable SID.
Move Routines
The system programming extensions provide the predefined procedures
move_l_to_r, move_r_to_l, fast_fill, and move_fast for generalized and
efficient data copying.
Move_L_to_R.
The predefined procedure move_l_to_r provides a generalized array copying
mechanism.
Usage
move_l_to_r(count,source,source_index,target,target_index)
Parameters
count A positive integer expression whose value is the
number of elements to move.
source The source array from where elements will be moved.
source_index An integer expression whose value is the index into
the source array of the leftmost element to be
moved. The value must be greater than or equal to
the index of the first element in the source array,
and less than or equal to the index of the last
element in the source array minus the move count.
target The target array to where elements are moved.
target_index An integer expression whose value is the index into
the target array to where the move begins. The
value must be greater than or equal to the index of
the first element in the target array, and less
than or equal to the index of the last element in
the target array minus the move count.
Description
The syntax of the procedure is identical to the syntax of the predefined
procedure strmove.
move_l_to_r moves elements from left to right. In a left to right move,
the first element to be moved is the left-most (lowest indexed) element,
and the last element to be moved is the right-most (highest indexed)
element.
Even if the elements of the array to be moved are arrays themselves, the
array will be moved as a single item.
The following diagram shows the order of copying elements for
move_l_to_r.
Figure 11-6. Copying Order for move_l_to_r
Example
TYPE
Index_Type_1 = 0..20;
Index_Type_2 = -3..17;
Array_Type_1 = PACKED ARRAY [Index_Type_1] of SHORTINT;
Array_Type_2 = ARRAY [Index_Type_2] of SHORTINT;
VAR
Array_1 = Array_Type_1;
Array_2 = Array_Type_2;
Index = Integer;
BEGIN
Move_L_to_R ( 5, Array_1, 3, Array_2, -3 )
{ is equivalent to: }
FOR Index := 0 TO 4 DO
Array_2[Index-3] := Array_1[3+Index]
{ is equivalent to: }
Array_2[-3] := Array_1[3]
Array_2[-2] := Array_1[4]
Array_2[-1] := Array_1[5]
Array_2[0] := Array_1[6]
Array_2[1] := Array_1[7]
Move_R_to_L.
The predefined procedure move_r_to_l provides a generalized array copying
mechanism.
Usage
move_r_to_l(count,source,source_index,target,target_index)
Parameters
count A positive integer expression whose value is the
number of elements to move.
source The source array from where elements will be moved.
source_index An integer expression whose value is the index into
the source array from where the move will begin.
The value must be greater than or equal to the
index of the first element in the source array, and
less than or equal to the index of the last element
in the source array minus the move count.
target The target array to where elements will be moved.
target_index An integer expression whose value is the index into
the target array to where the move will begin. The
value must be greater than or equal to the index of
the first element in the target array, and less
than or equal to the index of the last element in
the target array minus the move count.
Description
The syntax of the procedure is identical to the syntax of the predefined
procedure strmove.
move_r_to_l moves the elements from right to left. In a right to left
move, the first element to be moved is the right-most (highest indexed)
element, and the last element to be moved is the left-most (lowest
indexed) element.
Even if the elements of the array to be moved are arrays themselves, the
array will be moved as a single item.
The following diagram shows the order of copying for move_r_to_l.
Figure 11-7. Copying Order for move_r_to_l
Fast_Fill.
The predefined procedure fast_fill provides a generalized method of
initializing an array to a single 8 bit constant.
Usage
fast_fill (ptr,fill_char,count);
Parameters
ptr A pointer expression.
fill_char A constant expression.
count A positive integer expression that contains the
number of bytes to fill with fill_char.
Description
fast_fill provides a fast alternative to for loops or assignment
statements for initializing each element of a structure or an array to
the same 8 bit value.
fill_char and ptr should of compatible types. fill_char must also
satisfy the following requirement:
0 <= ord(fill_char) <=255
Example
$standard_level 'ext_modcal'$
program fill;
var p100 : packed array [1..100] of char;
var i1000 : packed array [1..1000] of integer;
type heap_p = array [0..9] of integer;
var p : ^heap_p;
begin
fast_fill(addr(p100),' ',sizeof(p100)); {fill a string array}
{with spaces.}
fast_fill(addr(i1000),0,sizeof(i1000)); {fill an integer array}
{with 0s. }
new(p);
fast_fill(p,hex('ff'),sizeof(p^)); {fill an array in the }
{heap to -1 (all bits on).}
end.
Move_Fast.
The predefined procedure move_fast provides another generalized array
copying mechanism.
Usage
move_fast(count,source,source_index,target,target_index)
Parameters
count A positive integer expression whose value is the
number of elements to move.
source The source array from where elements will be moved.
source_index An integer expression whose value is the index into
the source array of the leftmost element to be
moved. The value must be greater than or equal to
the index of the first element in the source array,
and less than or equal to the index of the last
element in the source array minus the move count.
target The target array to where elements will be moved.
target_index An integer expression whose value is the index into
the target array to where the move begins. The
value must be greater than or equal to the index of
the first element in the target array, and less
than or equal to the index of the last element in
the target array minus the move count.
Description
The syntax of the procedure is also identical to the syntax of the
predefined procedure, strmove.
Move_fast provides an alternative to move_l_to_r or move_r_to_l for
generating simpler and faster code when certain restrictions are met by
the parameters.
These restrictions are:
* The source and target arrays must not overlap.
* The source and the target must have elements with the same sizes.
The size of each element must be greater than or equal to one
byte.
* If the source or the target array is packed, then the packing
should be such that the wasted space per word; for example, space
left between elements, should be the same for both arrays.
* Both the source and the target arrays must be aligned on byte
boundaries. Therefore, one of the following must be true:
* All elements of the source and the target arrays must each
be aligned on byte boundaries.
* The leftmost source and target element must be aligned on
byte boundaries, and the total size of the elements to be
moved must be an integral multiple of one byte.
Example
{ This example assumes certain packing which may not apply to your
implementation. }
TYPE
IxType1 = 0..20;
IxType2 = -3..17;
Array1 = PACKED ARRAY [IxType1] of SHORTINT;
Array2 = ARRAY [IxType2] of SHORTINT;
Array3 = PACKED ARRAY [1..20] of -256..255;
Array4 = CRUNCHED ARRAY [1..20] of -256..255;
VAR
Avar1 : Array1;
Avar2 : Array2;
Avar3 : Array3;
Avar4 : Array4;
Ix : Integer;
BEGIN
Move_Fast (5, AVar2, -3, AVar1, 3); { legal }
FOR Ix := 0 TO 4 DO { equivalent FOR loop }
AVar1[Ix+3] := AVar2[Ix-3];
Move_Fast (5, AVar3, 2, AVar4, 9);
{ illegal, because }
{ - AVar4 does not have byte-aligned elements }
{ - AVar4[9] starts on the 27th bit of a word }
{ (also not byte-aligned) }
{ besides, the number of bits to be moved is not a }
{ multiple of eight, anyway }
Move_Fast (8, AVar4, 1, AVar4, 9)
{ legal, because }
{ - even though the individual elements of AVar4 are }
{ not byte-aligned, }
{ - AVar4[1] and AVar4[9] are each byte-aligned, and }
{ - The total size of the elements to be moved is an }
{ integral multiple of eight. }
END;
Error Handling Routines
Escape.
Usage
escape(escape_value)
Parameters
escape_value An integer expression whose value will be available
through the predefined function escapecode.
Description
Calling this predefined procedure indicates that a software error has
been detected. Execution passes to the statement following the reserved
word RECOVER of the first enclosing TRY-RECOVER statement.
The parameter is evaluated before control is passed and, its value is
available to the escapecode function.
If escape is called with no surrounding TRY-RECOVER the program aborts.
Example
PROCEDURE proc;
...
BEGIN
...
IF ( {something has gone wrong} ) THEN
ESCAPE( 0 );
...
END;
...
BEGIN
TRY
...
proc;
...
RECOVER
WRITELN( 'fatal error. program terminates' );
END.
Escapecode.
The predefined function escapecode returns the last execution error
number.
Usage
escapecode
The function returns the value passed to the last implicit or explicit
call to the predefined procedure escape.
An explicit call to escape is a call that was made by the user. In this
case escapecode returns the value of the escape code passed by the user.
An implicit call to escape is a call that was made by a subsystem on the
user's behalf or by the run-time library. In this case, escapecode
returns a predefined value based on the type of error detected. See the
HP Pascal/iX Programmer's Guide or the HP Pascal/HP-UX Programmer's
Guide, depending on your implementation, for more details about the
escape code values.
If escape has never been called (implicitly or explicitly), the value
returned by escapecode is undefined. If escapecode is called outside of
the recover part of a TRY-RECOVER statement, the value returned is
undefined.
Example
TRY
...
{ perform normal processing }
RECOVER
CASE escapecode OF
...
{ fix-up after an error that can be handled }
OTHERWISE
{ send errors that cannot be handled }
escape( escapecode );
END;
The example above shows a possible control structure for trapping
software errors. Within the recover section of the TRY-RECOVER
statement, escapecode is used to recover information about the nature of
the error that caused the trap to the recover section. Note the use of
escapecode to pass certain errors on to a next enclosing TRY statement
with an explicit call to escape.
Parameter Mechanisms
Haveextension.
The predefined Boolean function haveextension determines if an extension
parameter is accessible.
Usage
haveextension(parameter_name)
Parameters
parameter_name The name of a formal parameter in the current scope
or a containing scope that is EXTENSIBLE.
In a routine with extension parameters it may be necessary to check a
formal parameter to ensure that an actual parameter was supplied, as a
result of a parameter being passed by the user or being defaulted. The
predefined function haveextension indicates, for a formal extension
parameter name, whether that parameter exists and can be accessed.
Example
PROCEDURE proc_with_opt_parms( parm1 : type1;
VAR parm2 : type2;
parm3 : type3;
VAR parm4 : type4 )
OPTION EXTENSIBLE 2;
BEGIN
...
IF (haveextension( parm4 )) THEN
{ implies that parm4 and parm3 have values }
...
IF (haveextension( parm3 )) THEN
{ implies that parm3 has values }
...
...
END;
proc_with_opt_parms( var1, var2 );
...
proc_with_opt_parms( var1, var2, var3 );
In the previous example, haveextension is used to determine whether
either or both of the EXTENSIBLE parameters are passed in the call to the
procedure. Note that if parm4 is present, then by definition parm3 must
also be present. See the description of routine OPTION EXTENSIBLE for
more information.
In the first call to proc_with_opt_parms, both calls to haveextension
return false because none of the extension parameters are passed. In the
second call, haveextension returns true for the third parameter only.
PROCEDURE proc_with_opt_parms( parm1 : type1;
VAR parm2 : type2;
parm3 : type3;
VAR parm4 : type4 )
OPTION EXTENSIBLE 2
DEFAULT_PARMS ( parm3 := 0,
parm4 := nil );
BEGIN
...
IF (haveextension( parm3 )) THEN
...
IF (haveextension( parm4 )) THEN
...
...
END;
In the above example, haveextension( parm4 ) returns true only if the
fourth parameter was actually supplied by the user. If it was not
supplied, then the default value is ignored, and the parameter is not
passed.
Haveextension( parm3 ) is true if either of the following conditions are
true:
* The third or fourth parameters are supplied by the user.
* The fourth parameter is supplied and the third is defaulted.
Because the fourth parameter is EXTENSIBLE, and, therefore, by
definition all parameters to its left must be passed, the default
value for the third parameter is passed even though it was not
supplied by the user.
Haveoptvarparm.
The predefined Boolean function haveoptvarparm determines if a default
reference parameter is accessible.
Usage
haveoptvarparm(parameter_name)
Parameters
parameter_name The name of a default formal parameter of this or a
containing scope.
In a routine with default reference parameters, it may be necessary to
check a formal parameter to ensure that its actual parameter was supplied
by the user. The predefined function haveoptvarparm indicates for a
formal reference parameter name whether the corresponding actual
parameter was supplied by the user.
The argument to haveoptvarparm must be the name of a formal parameter
that:
* Is a VAR, ANYVAR, or PROCEDURE/FUNCTION parameter.
* Specifies a default value of NIL. See the routine OPTION
DEFAULT_PARMS.
Example
PROCEDURE proc_with_opt_parms( VAR parm1 : type1;
VAR parm2 : type2;
VAR parm3 : type3 )
OPTION DEFAULT_PARMS( parm2 := nil,
parm3 := nil );
BEGIN
...
IF (haveoptvarparm( parm2 )) THEN { ok to use parm2 }
...
IF (haveoptvarparm( parm3 )) THEN { ok to use parm3 }
...
END;
The procedure proc_with_opt_parms in the previous example has three VAR
parameters, two of which are optional. Before using one of the two
parameters within proc_with_opt_parms, a check is made to ensure that the
parameters were supplied by the user. This check is accomplished by
calling haveoptvarparm with the name of the parameter in question as its
argument.
Routine Mechanisms
Call.
The predefined procedure call invokes a procedure.
Usage
call(procedure_expression)
call(procedure_expression,parameter ...)
Parameters
procedure_expression An expression whose value is a reference to a
procedure whose formal parameter list is congruent
with the parameters specified in the call.
parameter An actual parameter that is compatible with the
corresponding formal parameter of the PROCEDURE
type of procedure_expression, that is passed to
the invoked procedure.
Description
The predefined procedure call causes the indicated procedure to be called
with the indicated parameters.
If, during the execution of the procedure, call accesses any non-local
variables, the variables accessed are the variables that were accessible
at the time the reference to the procedure was made, when it was passed
as an argument to the predefined function, addr. It is an error if the
procedure expression has the value NIL or is undefined. It may not be
possible to detect an undefined procedure reference.
Example
TYPE
procedure_type = PROCEDURE( i : integer );
VAR
int : integer;
proc_var : procedure_type;
PROCEDURE proc( int : integer );
BEGIN
...
END;
BEGIN
proc( int );
proc_var := addr( proc );
call( proc_var, int );
END;
In the above example, the two calls to the routine proc are effectively
identical.
Fcall.
The predefined function fcall invokes a function.
Usage
fcall(function_expression)
fcall( function_expression, parameter ... )
Parameters
function_expression An expression whose value is a reference to a
function whose formal parameter list is congruent
with the parameters specified in the call.
parameter An actual parameter that is compatible with the
corresponding formal parameter of the FUNCTION
type of function_expression, that is passed to the
invoked function.
The predefined function fcall causes the function referenced by the first
FUNCTION variable parameter to be invoked with the supplied parameters.
The type returned by fcall is the same as the type returned by the
FUNCTION expression.
See the description of call for more information.
Size Functions
Bitsizeof.
The predefined function bitsizeof returns an integer representing the
size of its argument in bits.
Usage
bitsizeof(variable)
bitsizeof(record_variable,tag_value ...)
bitsizeof(type_name)
bitsizeof(record_type_name,tag_value ...)
bitsizeof(struc_constant)
bitsizeof(string_literal)
Parameters
variable The name of a variable.
record_variable The name of a record variable with variants.
tag_value The name of a case constant in the variant part of a
record declaration. Case constants for nested
variants may appear separated by commas.
type_name The name of a type.
record_type_name The name of a record type with variants.
struc_constant The name of an array, record, set, or string
constructor.
string_literal A string literal.
The bitsizeof function returns the number of bits needed to represent the
data value part of a data item of the given type, or the actual allocated
size of a variable. If the first parameter is a record type or variable
with variants, a variant may be selected by specifying a case constant
with the subsequent parameters. Otherwise, the size with the largest
variant is used.
bitsizeof(type) returns the minimum number of bits of storage for the
type, and bitsizeof(variable) returns the number of bits of storage for
the variable.
For an ANYVAR parameter, two cases exist: If an additional hidden size
parameter is passed along with the ANYVAR parameter, bitsizeof gives the
number of bits in the number of bytes allocated to represent the actual
parameter. If the hidden length parameter is not passed, bitsizeof gives
the number of bits required to represent the formal parameter as a given
type.
Example
TYPE
int_type = integer;
rec_type = RECORD
int : integer;
CASE flag: Boolean OF
true: ( r : real );
false:( lr : longreal );
end;
VAR
int : int_type;
rec : rec_type;
size : integer;
BEGIN
...
size := bitsizeof( int );
size := bitsizeof( int_type );
size := bitsizeof( rec, true );
...
END;
NOTE bitsizeof is allowed in CONST declarations except for ANYVAR, VAR
string, and conformant array parameters.
Sizeof.
The predefined function sizeof returns an integer representing the size
of its argument in bytes.
Usage
sizeof(variable)
sizeof(record_variable,tag_value ...)
sizeof(type_name)
sizeof(record_type_name,tag_value ...)
sizeof(struct_constant)
sizeof(string_literal)
Parameters
variable The name of a variable.
record_variable The name of a record variable with variants.
tag_value The name of a case constant in the variant part of a
record declaration. Case constants for nested
variants may appear separated by commas.
type_name The name of a type.
record_type_name The name of a record type with variants.
struct_constant The name of an array, record, set, or string
constructor.
string_literal A string literal.
The predefined function sizeof returns the number of bytes of storage
required to represent the data value part of a data item of the given
type, or the actual allocated size of a variable. If the first parameter
is a record type or variable with variants, a variant may be selected by
specifying a case constant with the subsequent parameters. sizeof(type)
returns the minimum number of bytes for the type. sizeof(variable)
returns the number of bytes of storage for the variable. Otherwise, the
size of the largest variant is returned.
For a variable of a simple data type, the number returned by sizeof is
equivalent to the storage required for the variable in the unpacked
context. For example, if the variable is type char or Boolean, sizeof
returns 1.
For an ANYVAR parameter, two cases exist: If an additional hidden size
parameter is passed along with the ANYVAR parameter, sizeof gives the
actual number of bytes allocated to represent the actual parameter. If
the hidden length parameter is not passed, sizeof gives the number of
bytes required to represent the formal parameter.
For conformant array parameters, the function sizeof is the actual size
of the parameter.
Example
TYPE
byte = 0..255;
big_record = RECORD CASE Boolean OF
true: ( arr : array [ 1..200 ] of byte ):
false: ( f1 : integer;
...
f99 : char );
BEGIN
...
IF (sizeof(big_record,true) <> sizeof(big_record,false)) THEN
BEGIN
writeln ( 'variant size mismatch by',
abs(sizeof(big_record,true)-sizeof(big_record,false)):1,
'bytes' );
HALT (1);
END;
...
END.
NOTE sizeof is allowed in CONST sections except for ANYVAR, VAR s, and
conformant array parameters.
MPE/iX 5.0 Documentation