[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

HP Pascal for OpenVMS
Language Reference Manual


Previous Contents Index


TYPE
   {   Legal schema types:    }
   Range1( a, b : INTEGER ) = SET OF a..b+1;  {Run-time bounds checking}

   My_Record( Number_Size, Status_Size : INTEGER ) = RECORD
      Part_Number : PACKED ARRAY[1..Number_Size] OF INTEGER;
      Status     : STRING( Status_Size );    {Nested schema}
      END;

   Range2( Low, Span : INTEGER ) = Low..Low + Span;
   My_Integer( Dummy : INTEGER ) = -MAXINT-1..MAXINT;
   Matrix( Bound : INTEGER ) = ARRAY[1..Bound, 1..Bound] OF REAL;

   {    Illegal schema types (they do not form "new" types):   }
   My_String( Len : INTEGER ) = VARYING[Len] OF CHAR;
   My_Integer( Dummy : INTEGER ) = INTEGER;

2.6 String Types

You can use schema and data types to store and to manipulate character strings. These types have the following order of complexity:

  1. CHAR type
  2. PACKED ARRAY OF CHAR user-defined types
  3. VARYING OF CHAR user-defined types
  4. STRING predefined schema

Objects of the CHAR data type are character strings with a length of 1 and are lowest in the order of character string complexity. You can assign CHAR data to variables of the other string types.

The PACKED ARRAY OF CHAR types allow you to specify fixed-length character strings. The VARYING OF CHAR types are a HP Pascal extension that allows you to specify varying-length character strings with a constant maximum length. The STRING types provide a standard way for you to specify storage for varying-length character strings with a maximum length that can be specified at run time.

To provide values for variables of these types, you should use a character-string constant (or an expression that evaluates to a character string) instead of an array constructor. Using array constructors with STRING and VARYING OF CHAR types generates an error; to use array constructors with PACKED ARRAY OF CHAR types, you must specify component values for every element in the array (otherwise, you generate an error).

Consider the following example:


VAR
   String1 :

VARYING[10] OF CHAR

Generally, you can use any member of the ASCII character set in character-string constants and expressions. However, some members of the ASCII character set, including the bell, the backspace, and the carriage return, are nonprinting characters. The extended string format for character strings with nonprinting characters is as follows:


{'printing-string'({ordinal-value},...)}...

printing-string

A character-string constant.

Consider the following example:



'Two bells'(7,7)' in a null-terminated ASCII string.'(0)

HP Pascal provides the substring access notation to denote a piece of a string variable, string constant, or string function. The lower-bound and upper-bound are index-expressions. Consider the following:


string-access "[" lower-bound ".." upper-bound "]"

The following is an example:


   var s : packed array [1..10] of char;

   s[1..5] :='hello';
   s[6..10] := 'world';

In the executable-section of a block, these lower and upper bound expressions can be run-time expressions and are checked for validity if compiled with checking code enabled. You can also pass these string pieces to VAR parameters. For example:


  procedure do_buf(var p : packed array [1..u:integer] of char);
     begin p := '12345'; end;

  var buff : packed array [1..10] of char;

  do_buff(buff[1..5]);
  do_buff(buff[6..10);

  writeln(buff);

To avoid compile-time warning messages about passing components of PACKED structures to VAR parameters, use /USAGE=NOPACKED_ACTUALS to compile.

In expressions, substring access behaves much like the SUBSTR built-in.

HP Pascal also provides features for handling null-terminated strings. These are useful for communicating with routines written in the C language and on UNIX systems.

For More Information:

2.6.1 PACKED ARRAY OF CHAR Types

User-defined packed arrays of characters with specific lower and upper bounds provide a method of specifying fixed-length character strings. The string's lower bound must equal 1. The upper bound establishes the fixed length of the string.

The following example shows a declaration of a character string variable of twenty characters:


VAR
   My_String : PACKED ARRAY[1..20] OF CHAR;

Note

If the upper bound of the array exceeds 65,535, if the PACKED reserved word is not used, or if the array's components are not byte-sized characters, the compiler does not treat the array as a character string.

To assign values to fixed-length character strings, you can use a character-string constant (or an expression that evaluates to a character string). When assigning into fixed-length strings, the compiler adds blanks to extend a string shorter than the maximum characters declared. If you specify a string longer than the maximum characters declared, an error occurs. You can also use an array constructor as long as you specify characters for every component of the array as specified in the declaration. Consider the following example:


VAR
   States : PACKED ARRAY[1..20] OF CHAR
            VALUE 'Hello';                         {Is legal}
   States : PACKED ARRAY[1..20] OF CHAR
            VALUE [1:'H';2:'e';3:'l';4:'l';5:'o']  {Generates
                                                    an error}
   States : PACKED ARRAY[1..20] OF CHAR
            VALUE [1:'H';2:'e';3:'l';4:'l';5:'o';
                  OTHERWISE ' ']                   {Is legal,
                                                    but awkward}

For More Information:

2.6.2 VARYING OF CHAR Types

The VARYING OF CHAR user-defined types are an HP Pascal extension that provides a way of declaring variable-length character strings with a constant maximum length. If you require portable code, use the STRING predefined schema types to specify variable-length character strings.

VARYING OF CHAR types have the following form:


VARYING [upper-bound] OF [[attribute-list]] CHAR

upper-bound

An integer in the range from 1 through 65,535 that indicates the length of the longest possible string.

attribute-list

One or more identifiers that provide additional information about the VARYING OF CHAR string component.

You can assign string constants to VARYING OF CHAR variables from length 0 to the specified upper-bound. The compiler allocates enough storage space to hold a string of the maximum length. A VARYING OF CHAR variable with length 0 is the empty string (''). You can only use character-string constants (or expressions that evaluate to character strings) to assign values to variables of these types; you cannot use standard array constructors. Also, you can initialize a character string to the empty string (''), as follows:



VAR
   String1 : VARYING[10] OF CHAR VALUE '';

The VARYING OF CHAR variable is stored as though it were a record with two fields, as follows:



RECORD
   LENGTH   : [WORD] 0..upper-bound;  {Length of current string}
   BODY     : PACKED ARRAY[1..upper-bound] OF CHAR;  {Current string}
   END;

You can access the LENGTH and BODY predeclared identifiers as you would access fields of a record. For example, to determine the maximum length of a VARYING OF CHAR variable, use the SIZE predeclared function and the BODY predeclared identifier, as follows:


VAR
   String1 : VARYING[10] OF CHAR VALUE 'Wolf';
{In the executable section: }
Max_Length := SIZE( string1.BODY );
WRITELN( Max_Length );                {writes '10'}

To determine the current length of a VARYING OF CHAR variable, use the LENGTH predeclared function. From the previous example, the result of LENGTH( String1 ) is the same as String1.LENGTH.

You can refer to individual array components as you would individual components of any array, as follows:



String1[8] := 'L';

You cannot specify an index value that is greater than the length of the current string. HP Pascal does not pad remaining characters in the current string with blanks (' '). If you specify an index that is greater than the current length of the string, an error occurs.

For More Information:

2.6.3 STRING Schema Type

The STRING predefined schema provides a way of declaring variable-length character strings. The compiler stores STRING data as though it were stored in the following schema definition:


TYPE
   STRING( capacity : INTEGER ) = VARYING[capacity] OF CHAR;

The syntax of the discriminated schema is as follows:


STRING( capacity )

capacity

An integer in the range 1..65,535 that indicates the length of the longest possible string.

To use the predefined STRING schema, you provide an upper bound as the actual discriminant, as in the following example:


VAR
   Short_String : STRING( 5 );    {Maximum length of 5 characters}
   Long_String  : STRING( 100 );  {Maximum length of 100 characters}

You can assign string constants to STRING variables from length 0 to the specified upper bound. The compiler allocates enough storage space to hold a string of the maximum length. A STRING variable with length 0 is the empty string (''). To provide values for variables of this type, you must use character-string constants (or expressions that evaluate to character strings); you cannot use array constructors. Also, you can initialize a character string to the empty string (''), as follows:


VAR
   Short_String : STRING( 5 ) VALUE '';

You can access the CAPACITY predeclared identifier as you would a schema discriminant, and you can access the LENGTH and BODY predeclared identifiers as you would access fields of a record. The CAPACITY identifier allows you to access the actual discriminant of the STRING schema; the LENGTH identifier allows you to access the current length of the string object; and the BODY identifier contains the current string object, including whatever is in memory up to the capacity of the discriminated schema, as shown in the following example:


VAR
   String1 : STRING( 10 ) VALUE 'Wolf';
{In the executable section: }
WRITELN( String1.CAPACITY );  {prints '10'}
WRITELN(

String1.LENGTH

{prints '4'}

The value String1.BODY contains the four-character string 'Wolf' followed by whatever is currently stored in memory for the remaining six characters.

To determine the current length of a STRING variable, you can use the LENGTH predeclared function. The result of LENGTH( String1 ) is the same as String1.LENGTH.

You can refer to individual STRING components as you would individual components of any array, as follows:


String1[5] := 't';

The compiler does not pad remaining characters in the current string with blanks (' '). If you specify an index that is greater than the current length of the string an error occurs. Consider the following example:


VAR
   String1 : STRING( 10 ) VALUE 'Wombat';
   x       : CHAR;
{In the executable section:}
x := String1[9];       {Generates an error}
x := String1.BODY[9];  {Provides whatever is in memory there}
x := String1[5];       {Is legal}
String1[9] := 'X';     {Generates an error}

For More Information:

2.7 Null-Terminated Strings

HP Pascal includes routines and a built-in type to better coexist with null-terminated strings in the C language.

The C_STR_T datatype is equivalent to:


C_STR_T = ^ ARRAY [0..0] OF CHAR;

C_STR_T is a pointer to an ARRAY OF CHARs. It does not allocate memory for any character data. C_STR_T behaves like a normal pointer type in that you can assign NIL into it and the optional pointer checking code will check for dereferencing of a NIL pointer. The individual characters can be used by dereferencing the pointer and using an array index.

In these cases, no bounds checking will be performed even if array bounds checking is enabled. However, you cannot dereference a C_STR_T pointer without also indexing a single character. If you want to access an entire null-terminated string, see the PAS_STR function.

For More Information:

2.8 TIMESTAMP Type

The TIMESTAMP predefined type is used in conjunction with the GETTIMESTAMP procedure and with the DATE or TIME functions. GETTIMESTAMP initializes a variable of type TIMESTAMP; DATE and TIME function parameters are of type TIMESTAMP.

The TIMESTAMP data type is similar to the following record definition:


TIMESTAMP = PACKED RECORD
   DATEVALID, TIMEVALID   : BOOLEAN;
   YEAR                   : INTEGER;
   MONTH                  : 1..12;
   DAY                    : 1..31;
   HOUR                   : 0..23;
   MINUTE                 : 0..59;
   SECOND                 : 0..59;

    { The last 3 fields are OpenVMS systems only. }
   HUNDREDTH              : 0..99;
   BINARY_TIME            : [QUAD] RECORD L1,L2:INTEGER END;
                                  {64-bit VMS binary time:}
   DAY_OF_WEEK            : 1..7;   {1 is Monday and 7 is Sunday}

   END;

For More Information:

2.9 Static and Nonstatic Types

Static types are types whose objects can be fully described at compile time. For example, the variables a and b are derived from static types in the following example:


VAR
   a : INTEGER;
   b : ARRAY[1..10] OF INTEGER;

Nonstatic types are types whose objects potentially cannot be fully described at compile time (the type has a component that can be a run-time value). Nonstatic types include the following types:

  • Discriminated and undiscriminated schema types
  • Any type that contains a nonstatic component or index type

Nonstatic types require storage allocation to hold information about the type at run time. This storage, called the control part, includes information that cannot be determined until execution time; HP Pascal needs this information to allocate and to access variables and record fields of this type.

Consider the following nonstatic types:


TYPE
                               {Template is nonstatic:}
   Template( Upper : INTEGER ) = ARRAY[1..Upper] OF INTEGER;
   a = ^Template;                     {a's base type is nonstatic}
   b = Template( 5 );                 {b is nonstatic}
   My_Subrange( x, y : INTEGER ) = x..y;
                                      {c is nonstatic:}
   c = ARRAY[My_Subrange( j, k ), My_Subrange( l, m )] OF INTEGER;
   d = ARRAY[1..10] OF Template( 5 ); {d is nonstatic}
   e = RECORD                         {e is nonstatic}
      f1 : TEMPLATE( 5 );
      END;
   f = SET OF My_Subrange( 10, 20 );  {f is nonstatic}

Do not confuse static and nonstatic types with automatic and static variable allocation.

For More Information:

2.10 Type Compatibility

The following sections discuss the two forms of type compatibility: structural and assignment compatibility.

2.10.1 Structural Compatibility

Two types are structurally compatible only if they have the same allocation size and the same type structure. HP Pascal requires that the type of a variable passed to a routine as an actual parameter be structurally compatible with the type of the corresponding formal variable parameter. HP Pascal also checks the structural compatibility of the base types when a pointer expression is assigned to a pointer variable. Structural compatibility does not apply to nonstatic types (schema types and types derived from schema types).

Two ordinal types are structurally compatible only if they have the same base type and the same allocation size.

If two ordinal types are components of packed structured types, they are structurally compatible only if the ranges of values they describe have identical upper and lower bounds.

In general, each real type is structurally compatible only with itself. However, because REAL and SINGLE are synonymous, they are structurally compatible with each other.

For two structured types to be structurally compatible, they must have the same allocation size, and both must be packed or both unpacked. The following conditions also affect structural compatibility:

  • If both types are record types, they must have the same number of fields, and the types of corresponding fields must be structurally compatible and identically positioned. If the record types have variant parts, the corresponding variants must have identical case labels written in the same order. The types of the fields within corresponding variants must be structurally compatible.
  • If both types are array types, the types of their components must be structurally compatible. The index types must have identical base types and identical upper and lower bounds.
  • If both types are VARYING OF CHAR types, their maximum lengths must be equal. The lengths of the current values of the VARYING OF CHAR strings do not affect structural compatibility.
  • If two components of packed structured types are set types, their base types must have identical upper and lower bounds.
  • If both types are set types, file types, or pointer types, their base types must be structurally compatible. Because of the possibility that a pointer type can be defined in terms of itself, the HP Pascal compiler begins the test for the structural compatibility of two pointer types by assuming that they are compatible. Next, the compiler tests the two base types for structural compatibility. If within the base type, the compiler encounters the same pointer types it is testing, it still follows the original assumption that the pointer types are compatible. If the base types prove to be structurally compatible, then the two pointer types are judged to be structurally compatible.

For More Information:


Previous Next Contents Index